usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c
author masputra
Sat, 22 Oct 2005 22:50:14 -0700
changeset 741 40027a3621ac
parent 198 93f223a7d535
child 1676 37f4a3e2bd99
permissions -rw-r--r--
PSARC 2005/082 Yosemite: UDP Performance Enhancement 4796051 Solaris needs a more complete HW checksumming support 4905227 duplicate macros in ipclassifier.h and ip.h 4915681 need hardware checksum offload for the case of IP/UDP reassembly 6201076 outbound flow-control dysfunctional, ip to ce using mdt 6223331 ipv6 flow control may corrupt UDP packets 6223809 16-bit aligned IP header should be allowed for all x86 platforms 6275398 Galaxy hangs when running lmbench 6281836 Yosemite project integration into Solaris 6281885 xge needs to support IPv6 checksum offload 6282776 IPv6 NCE fast path is not created for incoming solicitation 6304890 IP transmit-side checksum logic needs to be tightened 6304902 IP6_IN_NOCKSUM is obsolete and should be torched 6304904 UDP should reject TI_GETPEERNAME for non-connected endpoint 6306768 IP and UDP device and module definitions need to be centralized
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * Copyright (c) 1983 Regents of the University of California.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * All rights reserved.  The Berkeley software License Agreement
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * specifies the terms and conditions for redistribution.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
#include "defs.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
#include "strings.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
#include "ifconfig.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
#include <compat.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
#include <sys/dlpi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
#include <libdlpi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 198
diff changeset
    21
#include <inet/ip.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 198
diff changeset
    22
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
#define	LOOPBACK_IF	"lo0"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
#define	NONE_STR	"none"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#ifndef	ARP_MOD_NAME
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
#define	ARP_MOD_NAME	"arp"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#define	ADDRBITS_V4	32	/* number of bits in IPv4 address */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#define	ADDRBITS_V6	128	/* number of bits in IPv6 address */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#define	AF_FUNC_STATUS		1	/* af_status func reports status */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#define	AF_FUNC_CONFIGINFO	2	/* af_status func reports configinfo */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
typedef struct if_flags {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
	uint64_t iff_value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
	char	*iff_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
} if_flags_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
static if_flags_t	if_flags_tbl[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
	{ IFF_UP,		"UP" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
	{ IFF_BROADCAST,	"BROADCAST" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
	{ IFF_DEBUG,		"DEBUG" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
	{ IFF_LOOPBACK,		"LOOPBACK" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
	{ IFF_POINTOPOINT,	"POINTOPOINT" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
	{ IFF_NOTRAILERS,	"NOTRAILERS" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
	{ IFF_RUNNING,		"RUNNING" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
	{ IFF_NOARP,		"NOARP" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
	{ IFF_PROMISC,		"PROMISC" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
	{ IFF_ALLMULTI,		"ALLMULTI" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
	{ IFF_INTELLIGENT,	"INTELLIGENT" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
	{ IFF_MULTICAST,	"MULTICAST" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
	{ IFF_MULTI_BCAST,	"MULTI_BCAST" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
	{ IFF_UNNUMBERED,	"UNNUMBERED" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
	{ IFF_DHCPRUNNING,	"DHCP" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
	{ IFF_PRIVATE,		"PRIVATE" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
	{ IFF_NOXMIT,		"NOXMIT" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
	{ IFF_NOLOCAL,		"NOLOCAL" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
	{ IFF_DEPRECATED,	"DEPRECATED" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
	{ IFF_ADDRCONF,		"ADDRCONF" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
	{ IFF_ROUTER,		"ROUTER" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
	{ IFF_NONUD,		"NONUD" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
	{ IFF_ANYCAST,		"ANYCAST" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
	{ IFF_NORTEXCH,		"NORTEXCH" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
	{ IFF_IPV4,		"IPv4" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
	{ IFF_IPV6,		"IPv6" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
	{ IFF_MIPRUNNING,	"MIP" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
	{ IFF_NOFAILOVER,	"NOFAILOVER" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
	{ IFF_FAILED,		"FAILED" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
	{ IFF_STANDBY,		"STANDBY" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
	{ IFF_INACTIVE,		"INACTIVE" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
	{ IFF_OFFLINE,		"OFFLINE" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
	{ IFF_XRESOLV,		"XRESOLV" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
	{ IFF_COS_ENABLED,	"CoS" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
	{ IFF_PREFERRED,	"PREFERRED" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
	{ IFF_TEMPORARY,	"TEMPORARY" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
	{ IFF_FIXEDMTU,		"FIXEDMTU" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
	{ IFF_VIRTUAL,		"VIRTUAL"}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
static struct	lifreq lifr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
/* current interface name a praticular function is accessing */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
static char	name[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
/* foreach interface saved name */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
static char	origname[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
static char savedname[LIFNAMSIZ];	/* For addif */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
static int	setaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
static char partname[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
uid_t	euid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 * Make sure the algorithm variables hold more than the sizeof an algorithm
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 * in PF_KEY.  (For now, more than a uint8_t.)  The NO_***_?ALG indicates that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 * there was no algorithm requested, and in the ipsec_req that service should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
 * be disabled.  (E.g. if ah_aalg remains NO_AH_AALG, then AH will be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
 * disabled on that tunnel.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
#define	NO_AH_AALG 256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
#define	NO_ESP_AALG 256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
#define	NO_ESP_EALG 256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
 * iface_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
 * used by setifether to create a list of interfaces to mark
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
 * down-up when changing the ethernet address of an interface
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
typedef struct iface {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
	struct lifreq lifr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
	struct iface *next;	/* pointer to the next list element */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
} iface_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
static	iface_t	*logifs = NULL; /* list of logical interfaces */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
static 	iface_t	*phyif	= NULL;	/* physical interface */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
int	s;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
int	af = AF_INET;	/* default address family */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
int	debug = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
int	all = 0;	/* setifdhcp() needs to know this */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
int	verbose = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
int	v4compat = 0;	/* Compatible printing format */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
boolean_t	partial = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
 * Function prototypes for command functions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
static int	addif(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
static int	inetplumb(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
static int	inetunplumb(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
static int	removeif(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
static int	setdebugflag(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
static int	setifaddr(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
static int	setifbroadaddr(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
static int	setifdstaddr(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
static int	setifether(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
static int	setifflags(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
static int	setifindex(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
static int	setifmetric(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
static int	setifmtu(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
static int	setifnetmask(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
static int	setifprefixlen(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
static int	setifrevarp(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
static int	setifsubnet(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
static int	setiftdst(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
static int	setiftoken(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
static int	setiftsrc(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
static int	setverboseflag(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
static int	set_tun_ah_alg(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
static int	set_tun_esp_auth_alg(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
static int	set_tun_esp_encr_alg(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
static int	modlist(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
static int	modinsert(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
static int	modremove(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
static int	setifgroupname(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
static int	configinfo(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
static void	print_config_flags(uint64_t flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
static void	print_flags(uint64_t flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
static void	print_ifether(char *ifname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
static int	set_tun_encap_limit(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
static int	clr_tun_encap_limit(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
static int	set_tun_hop_limit(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
static int	setzone(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
static int	setifsrc(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
static int	setnd(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
static int	delnd(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
static int	getnd(char *arg, int64_t param);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
#endif /* DEBUG */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
 * Address family specific function prototypes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
static void	in_getaddr(char *s, struct sockaddr *saddr, int *plenp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
static void	in_status(int force, uint64_t flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
static void	in_configinfo(int force, uint64_t flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
static void	in6_getaddr(char *s, struct sockaddr *saddr, int *plenp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
static void	in6_status(int force, uint64_t flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
static void	in6_configinfo(int force, uint64_t flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
 * Misc support functions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
static int	devfs_entry(di_node_t node, di_minor_t minor, void *arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
static void	foreachinterface(void (*func)(), int argc, char *argv[],
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
		    int af, int64_t onflags, int64_t offflags,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
		    int64_t lifc_flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
static void	ifconfig(int argc, char *argv[], int af, struct lifreq *lifrp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
static int	ifdad(char *ifname, struct sockaddr_in6 *laddr);
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   192
static boolean_t	in_getmask(struct sockaddr_in *saddr,
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   193
			    boolean_t addr_set);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
static int	in_getprefixlen(char *addr, boolean_t slash, int plen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
static boolean_t	in_prefixlentomask(int prefixlen, int maxlen,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
			    uchar_t *mask);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
static int	settaddr(char *, int (*)(icfg_handle_t,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
			    const struct sockaddr *, socklen_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
static void	status(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
static void	ifstatus(const char *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
static void	usage(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
static int	strioctl(int s, int cmd, char *buf, int buflen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
static int	setifdhcp(const char *caller, const char *ifname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
		    int argc, char *argv[]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
static int	ip_domux2fd(int *, int *, int *, int *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
static int	ip_plink(int, int, int, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
static int	modop(char *arg, char op);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
static int	get_lun(char *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
static void	selectifs(int argc, char *argv[], int af,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
			struct lifreq *lifrp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
static int	updownifs(iface_t *ifs, int up);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
#define	max(a, b)	((a) < (b) ? (b) : (a))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
 * DHCP_EXIT_IF_FAILURE indicates that the operation failed, but if there
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
 * are more interfaces to act on (i.e., ifconfig was invoked with -a), keep
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
 * on going rather than exit with an error.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
#define	DHCP_EXIT_IF_FAILURE	-1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
#define	DHCP_IPC_MAX_WAIT	15	/* max seconds to wait to start agent */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
#define	NEXTARG		0xffffff	/* command takes an argument */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
#define	OPTARG		0xfffffe 	/* command takes an optional argument */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
#define	AF_ANY		(-1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
/* Refer to the comments in ifconfig() on the netmask "hack" */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
#define	NETMASK_CMD	"netmask"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
struct sockaddr_storage	g_netmask;
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   231
enum { G_NETMASK_NIL, G_NETMASK_PENDING, G_NETMASK_SET }
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   232
    g_netmask_set = G_NETMASK_NIL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
struct	cmd {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	char		*c_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
	int64_t		c_parameter;	/* NEXTARG means next argv */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	int		(*c_func)(char *, int64_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	int		c_abortonfail;	/* don't continue parsing args */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
					/* for the current interface */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
	int	c_af;			/* address family restrictions */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
} cmds[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
	{ "up",		IFF_UP,		setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
	{ "down",	-IFF_UP,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	{ "trailers",	-IFF_NOTRAILERS, setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	{ "-trailers",	IFF_NOTRAILERS,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	{ "arp",	-IFF_NOARP,	setifflags,	0,	AF_INET },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	{ "-arp",	IFF_NOARP,	setifflags,	0,	AF_INET },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	{ "router",	IFF_ROUTER,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
	{ "-router",	-IFF_ROUTER,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	{ "private",	IFF_PRIVATE,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
	{ "-private",	-IFF_PRIVATE,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
	{ "xmit",	-IFF_NOXMIT,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
	{ "-xmit",	IFF_NOXMIT,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
	{ "-nud",	IFF_NONUD,	setifflags,	0,	AF_INET6 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
	{ "nud",	-IFF_NONUD,	setifflags,	0,	AF_INET6 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
	{ "anycast",	IFF_ANYCAST,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
	{ "-anycast",	-IFF_ANYCAST,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
	{ "local",	-IFF_NOLOCAL,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
	{ "-local",	IFF_NOLOCAL,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
	{ "deprecated",	IFF_DEPRECATED,	setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	{ "-deprecated", -IFF_DEPRECATED, setifflags,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	{ "preferred",	IFF_PREFERRED,	setifflags,	0,	AF_INET6 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	{ "-preferred",	-IFF_PREFERRED,	setifflags,	0,	AF_INET6 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	{ "debug",	0,		setdebugflag,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	{ "verbose",	0,		setverboseflag,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
	{ NETMASK_CMD,	NEXTARG,	setifnetmask,	0,	AF_INET },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
	{ "metric",	NEXTARG,	setifmetric,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	{ "mtu",	NEXTARG,	setifmtu,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
	{ "index",	NEXTARG,	setifindex,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
	{ "broadcast",	NEXTARG,	setifbroadaddr,	0,	AF_INET },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	{ "auto-revarp", 0,		setifrevarp,	1,	AF_INET },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
	{ "plumb",	0,		inetplumb,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	{ "unplumb",	0,		inetunplumb,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	{ "subnet",	NEXTARG,	setifsubnet,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
	{ "token",	NEXTARG,	setiftoken,	0,	AF_INET6 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
	{ "tsrc",	NEXTARG,	setiftsrc,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
	{ "tdst",	NEXTARG,	setiftdst,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
	{ "encr_auth_algs", NEXTARG,	set_tun_esp_auth_alg, 0, AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
	{ "encr_algs",	NEXTARG,	set_tun_esp_encr_alg, 0, AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	{ "auth_algs",	NEXTARG,	set_tun_ah_alg,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	{ "addif",	NEXTARG,	addif,		1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	{ "removeif",	NEXTARG,	removeif,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	{ "modlist",	0,		modlist,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	{ "modinsert",	NEXTARG,	modinsert,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
	{ "modremove",	NEXTARG,	modremove,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	{ "failover",	-IFF_NOFAILOVER, setifflags,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
	{ "-failover",	IFF_NOFAILOVER, setifflags,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	{ "standby",	IFF_STANDBY,	setifflags,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	{ "-standby",	-IFF_STANDBY,	setifflags,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
	{ "failed",	IFF_FAILED,	setifflags,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	{ "-failed",	-IFF_FAILED,	setifflags,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	{ "group",	NEXTARG,	setifgroupname,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
	{ "configinfo",	0,		configinfo,	1,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
	{ "encaplimit",	NEXTARG,	set_tun_encap_limit,	0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
	    AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
	{ "-encaplimit", 0,		clr_tun_encap_limit,	0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
	    AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
	{ "thoplimit",	NEXTARG,	set_tun_hop_limit,	0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
	    AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
	{ "getnd",	NEXTARG,	getnd,		0,	AF_INET6 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
	{ "setnd",	NEXTARG,	setnd,		0,	AF_INET6 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	{ "delnd",	NEXTARG,	delnd,		0,	AF_INET6 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
/* XXX for testing SIOCT* ioctls. Remove */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
	{ "set",	NEXTARG,	setifaddr,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	{ "destination", NEXTARG,	setifdstaddr,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
	{ "zone",	NEXTARG,	setzone,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
	{ "-zone",	0,		setzone,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
	{ "ether",	OPTARG,		setifether,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
	{ "usesrc",	NEXTARG,	setifsrc,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
	{ 0,		0,		setifaddr,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
	{ 0,		0,		setifdstaddr,	0,	AF_ANY },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
	{ 0,		0,		0,		0,	0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
typedef struct if_config_cmd {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
	uint64_t	iff_flag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
	char		*iff_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
} if_config_cmd_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
static if_config_cmd_t	if_config_cmd_tbl[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	{ IFF_UP,		"up" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
	{ IFF_NOTRAILERS,	"-trailers" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
	{ IFF_PRIVATE,		"private" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	{ IFF_NOXMIT,		"-xmit" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
	{ IFF_ANYCAST,		"anycast" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	{ IFF_NOLOCAL,		"-local" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
	{ IFF_DEPRECATED,	"deprecated" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	{ IFF_NOFAILOVER,	"-failover" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
	{ IFF_STANDBY,		"standby" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	{ IFF_FAILED,		"failed" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	{ IFF_PREFERRED,	"preferred" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
	{ 0,			0 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
typedef struct ni {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	char		ni_name[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
	struct ni	*ni_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
} ni_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
static ni_t	*ni_list = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
static int	num_ni = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
/* End defines and structure definitions for ifconfig -a plumb */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
/* Known address families */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
struct afswtch {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	char *af_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	short af_af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
	void (*af_status)();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	void (*af_getaddr)();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	void (*af_configinfo)();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
} afs[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
	{ "inet", AF_INET, in_status, in_getaddr, in_configinfo },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
	{ "inet6", AF_INET6, in6_status, in6_getaddr, in6_configinfo },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
	{ 0, 0,	0, 0, 0 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
#define	SOCKET_AF(af)	(((af) == AF_UNSPEC) ? AF_INET : (af))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
struct afswtch *afp;	/* the address family being set or asked about */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
main(int argc, char *argv[])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
	/* Include IFF_NOXMIT, IFF_TEMPORARY and all zone interfaces */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
	int64_t lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
	char *default_ip_str;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
	if (argc < 2) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
		usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
	argc--, argv++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
	if (strlen(*argv) > sizeof (name) - 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
		(void) fprintf(stderr, "%s: interface name too long\n", *argv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
	(void) strncpy(name, *argv, sizeof (name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
	name[sizeof (name) - 1] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
	(void) strncpy(origname, name, sizeof (origname));	/* For addif */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	euid = geteuid();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
	default_ip_str = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
	v4compat = get_compat_flag(&default_ip_str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	if (v4compat == DEFAULT_PROT_BAD_VALUE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
		    "ifconfig: %s: Bad value for %s in %s\n", default_ip_str,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
		    DEFAULT_IP, INET_DEFAULT_FILE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
		free(default_ip_str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		exit(2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
	free(default_ip_str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
	argc--, argv++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
	if (argc > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
		struct afswtch *myafp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
		for (myafp = afp = afs; myafp->af_name; myafp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
			if (strcmp(myafp->af_name, *argv) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
				afp = myafp; argc--; argv++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
		af = lifr.lifr_addr.ss_family = afp->af_af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
		if (af == AF_INET6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
			v4compat = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
	s = socket(SOCKET_AF(af), SOCK_DGRAM, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
	if (s < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
		Perror0_exit("socket");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
	 * Special interface names is any combination of these flags.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
	 * Note that due to the ifconfig syntax they have to be combined
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
	 * as a single '-' option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
	 *	-a	All interfaces
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
	 *	-u	"up" interfaces
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
	 *	-d	"down" interfaces
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
	 *	-D	Interfaces not controlled by DHCP
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
	 *	-4	IPv4 interfaces
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	 *	-6	IPv6 interfaces
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	 *	-X	Turn on debug (not documented)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
	 *	-v	Turn on verbose
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	 *	-Z	Only interfaces in caller's zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	if (name[0] == '-') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
		/* One or more options */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
		int64_t onflags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
		int64_t offflags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
		int c;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
		char *av[2] = { "ifconfig", name };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
		while ((c = getopt(2, av, "audDXZ46v")) != -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
			switch ((char)c) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
			case 'a':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
				all = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
			case 'u':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
				onflags |= IFF_UP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
			case 'd':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
				offflags |= IFF_UP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
			case 'D':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
				offflags |= IFF_DHCPRUNNING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
			case 'X':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
				debug += 3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
			case 'Z':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
				lifc_flags &= ~LIFC_ALLZONES;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
			case '4':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
				 * -4 is not a compatable flag, therefore
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
				 * we assume they want v4compat turned off
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
				v4compat = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
				onflags |= IFF_IPV4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
			case '6':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
				 * If they want IPv6, well then we'll assume
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
				 * they don't want IPv4 compat
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
				v4compat = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
				onflags |= IFF_IPV6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
			case 'v':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
				verbose = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
			case '?':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
				usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
				exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
		if (!all) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
			(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
			    "ifconfig: %s: no such interface\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
			    name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
		foreachinterface(ifconfig, argc, argv, af, onflags, offflags,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
		    lifc_flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
		ifconfig(argc, argv, af, (struct lifreq *)NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
 * For each interface, call (*func)(argc, argv, af, lifrp).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
 * Only call function if onflags and offflags are set or clear, respectively,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
 * in the interfaces flags field.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
foreachinterface(void (*func)(), int argc, char *argv[], int af,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
    int64_t onflags, int64_t offflags, int64_t lifc_flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
	int n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
	char *buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
	struct lifnum lifn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
	struct lifconf lifc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
	struct lifreq *lifrp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	struct lifreq lifrl;	/* Local lifreq struct */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
	int numifs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
	unsigned bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	ni_t *nip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
	int plumball = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
	int save_af = af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
	 * Special case:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	 * ifconfig -a plumb should find all network interfaces
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
	 * in the machine by traversing the devinfo tree.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
	 * Also, there is no need to  SIOCGLIF* ioctls, since
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
	 * those interfaces have already been plumbed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	if (argc > 0 && (strcmp(*argv, "plumb") == 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
		 * Look through the kernel's devinfo tree for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
		 * network devices
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
		di_node_t root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
		 * DINFOCACHE is equivalent to DINFOSUBTREE | DINFOMINOR |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
		 * DINFOPROP | DINFOFORCE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
		if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
			(void) fprintf(stderr, "ifconfig: di_init failed;"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
			    " check the devinfo driver.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
		(void) di_walk_minor(root, DDI_NT_NET, DI_CHECK_ALIAS, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
		    devfs_entry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
		di_fini(root);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
		 * Now, translate the linked list into
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
		 * a struct lifreq buffer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
		bufsize = num_ni * sizeof (struct lifreq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
		if ((buf = malloc(bufsize)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
			Perror0_exit("foreachinterface: malloc failed");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
		lifc.lifc_family = AF_UNSPEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
		lifc.lifc_flags = lifc_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
		lifc.lifc_len = bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
		lifc.lifc_buf = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
		for (n = 0, lifrp = lifc.lifc_req; n < num_ni; n++, lifrp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
			nip = ni_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
			(void) strncpy(lifrp->lifr_name, nip->ni_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
			    sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
			ni_list = nip->ni_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
			free(nip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
		plumball = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
		lifn.lifn_family = AF_UNSPEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
		lifn.lifn_flags = lifc_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
		if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
			Perror0_exit("Could not determine number"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
			    " of interfaces");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
		numifs = lifn.lifn_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
		if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
			(void) printf("ifconfig: %d interfaces\n",  numifs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
		bufsize = numifs * sizeof (struct lifreq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
		if ((buf = malloc(bufsize)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
			Perror0("out of memory\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
			(void) close(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
		lifc.lifc_family = AF_UNSPEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
		lifc.lifc_flags = lifc_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
		lifc.lifc_len = bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
		lifc.lifc_buf = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
		if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
			Perror0("SIOCGLIFCONF");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
			(void) close(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
			free(buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	lifrp = lifc.lifc_req;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
	for (n = lifc.lifc_len / sizeof (struct lifreq); n > 0; n--, lifrp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
		if (!plumball) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
			 * We must close and recreate the socket each time
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
			 * since we don't know what type of socket it is now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
			 * (each status function may change it).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
			(void) close(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
			af = lifrp->lifr_addr.ss_family;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
			s = socket(SOCKET_AF(af), SOCK_DGRAM, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
			if (s == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
				 * Perror0() assumes the name to be in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
				 * globally defined lifreq structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
				(void) strncpy(lifr.lifr_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
				    lifrp->lifr_name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
				Perror0_exit("socket");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
		 * Only service interfaces that match the on and off
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
		 * flags masks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
		if (onflags || offflags) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
			(void) memset(&lifrl, 0, sizeof (lifrl));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
			(void) strncpy(lifrl.lifr_name, lifrp->lifr_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
				sizeof (lifrl.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
			if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifrl) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
				 * Perror0() assumes the name to be in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
				 * globally defined lifreq structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
				(void) strncpy(lifr.lifr_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
				    lifrp->lifr_name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
				Perror0_exit("foreachinterface: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
			if ((lifrl.lifr_flags & onflags) != onflags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
			if ((~lifrl.lifr_flags & offflags) != offflags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
		if (!plumball) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
			(void) strncpy(lifrl.lifr_name, lifrp->lifr_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
			    sizeof (lifrl.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
			if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifrl) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
				 * Perror0() assumes the name to be in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
				 * globally defined lifreq structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
				(void) strncpy(lifr.lifr_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
				    lifrp->lifr_name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
				Perror0("foreachinterface: SIOCGLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
			if (lifrl.lifr_addr.ss_family != af) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
				/* Switch address family */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
				af = lifrl.lifr_addr.ss_family;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
				(void) close(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
				s = socket(SOCKET_AF(af), SOCK_DGRAM, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
				if (s == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
					 * Perror0() assumes the name to be in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
					 * the globally defined lifreq
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
					 * structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
					(void) strncpy(lifr.lifr_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
					    lifrp->lifr_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
					    sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
					Perror0_exit("socket");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
		 * Reset global state
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
		 * setaddr: Used by parser to tear apart source and dest
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
		 * name and origname contain the name of the 'current'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
		 * interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
		setaddr = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
		(void) strncpy(name, lifrp->lifr_name, sizeof (name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
		(void) strncpy(origname, name, sizeof (origname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
		if (partial) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
			if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
				(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
				    "checking partial %s against %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
				    partname, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
			if (strncmp(name, partname, strlen(partname)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
		(*func)(argc, argv, save_af, lifrp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
		/* the func could have overwritten origname, so restore */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
		(void) strncpy(name, origname, sizeof (name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
	free(buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
tun_reality_check(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
	struct iftun_req treq;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
	ipsec_req_t *ipsr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
	(void) strncpy(treq.ifta_lifr_name, name, sizeof (treq.ifta_lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
	if (strchr(name, ':') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
		/* Return, we don't need to check. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	if (ioctl(s, SIOCGTUNPARAM, (caddr_t)&treq) < 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
	    (treq.ifta_flags & IFTUN_SECURITY) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
		 * Either not a tunnel (the SIOCGTUNPARAM fails on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
		 * non-tunnels), or the security flag is not set.  Either
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
		 * way, return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
	ipsr = (ipsec_req_t *)&treq.ifta_secinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
	if (ipsr->ipsr_esp_req != 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
	    ipsr->ipsr_esp_auth_alg == SADB_AALG_NONE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	    ipsr->ipsr_ah_req == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
		(void) fprintf(stderr, "ifconfig: WARNING - tunnel with "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
		    "only ESP and potentially no authentication.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
 * for the specified interface call (*func)(argc, argv, af, lifrp).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
ifconfig(int argc, char *argv[], int af, struct lifreq *lifrp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
	static boolean_t scan_netmask = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
	if (argc == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
		status();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
	if (strcmp(*argv, "auto-dhcp") == 0 || strcmp(*argv, "dhcp") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
		if (af == AF_INET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
			 * some errors are ignored in the case where
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
			 * more than one interface is being operated on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
			ret = setifdhcp("ifconfig", name, argc, argv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
			if (ret == DHCP_EXIT_IF_FAILURE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
				if (!all)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
					exit(DHCP_EXIT_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
			} else if (ret != DHCP_EXIT_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
				exit(ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
			(void) fprintf(stderr, "ifconfig: dhcp not supported "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
			    "for inet6\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
	 * The following is a "hack" to get around the existing interface
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
	 * setting mechanism.  Currently, each interface attribute,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
	 * such as address, netmask, broadcast, ... is set separately.  But
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
	 * sometimes two or more attributes must be set together.  For
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
	 * example, setting an address without a netmask does not make sense.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
	 * Yet they can be set separately for IPv4 address using the current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
	 * ifconfig(1M) syntax.  The kernel then "infers" the correct netmask
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
	 * using the deprecated "IP address classes."  This is simply not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
	 * correct.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	 * The "hack" below is to go thru the whole command list looking for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	 * the netmask command first.  Then use this netmask to set the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	 * address.  This does not provide an extensible way to accommodate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
	 * future need for setting more than one attributes together.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
	 *
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   784
	 * Note that if the "netmask" command argument is a "+", we need
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   785
	 * to save this info and do the query after we know the address to
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   786
	 * be set.  The reason is that if "addif" is used, the working
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   787
	 * interface name will be changed later when the logical interface
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   788
	 * is created.  In in_getmask(), if an address is not provided,
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   789
	 * it will use the working interface's address to do the query.
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   790
	 * It will be wrong now as we don't know the logical interface's name.
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   791
	 *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
	 * ifconfig(1M) is too overloaded and the code is so convoluted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
	 * that it is "safer" not to re-architect the code to fix the above
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
	 * issue, hence this "hack."  We may be better off to have a new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
	 * command with better syntax for configuring network interface
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	 * parameters...
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
	if (!scan_netmask && afp->af_af == AF_INET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
		int	largc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
		char	**largv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
		/* Only go thru the command list once to find the netmask. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
		scan_netmask = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
		 * Currently, if multiple netmask commands are specified, the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
		 * last one will be used as the final netmask.  So we need
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
		 * to scan the whole list to preserve this behavior.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
		for (largc = argc, largv = argv; largc > 0; largc--, largv++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
			if (strcmp(*largv, NETMASK_CMD) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
				if (--largc == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
				largv++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
				if (strcmp(*largv, "+") == 0) {
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   816
					g_netmask_set = G_NETMASK_PENDING;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
					in_getaddr(*largv, (struct sockaddr *)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
					    &g_netmask, NULL);
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   820
					g_netmask_set = G_NETMASK_SET;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
				/* Continue the scan. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
	while (argc > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
		struct cmd *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
		boolean_t found_cmd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
		if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
			(void) printf("ifconfig: argv %s\n", *argv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
		found_cmd = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
		for (p = cmds; p->c_func; p++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
			if (p->c_name) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
				if (strcmp(*argv, p->c_name) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
					 * indicate that the command was
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
					 * found and check to see if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
					 * the address family is valid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
					found_cmd = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
					if (p->c_af == AF_ANY ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
					    af == p->c_af)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
						break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
				if (p->c_af == AF_ANY ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
				    af == p->c_af)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
		 * If we found the keyword, but the address family
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
		 * did not match spit out an error
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
		if (found_cmd && p->c_name == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
			(void) fprintf(stderr, "ifconfig: Operation %s not"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
			    " supported for %s\n", *argv, afp->af_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
		 * else (no keyword found), we assume it's an address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
		 * of some sort
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
		if (p->c_name == 0 && setaddr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
			p++;	/* got src, do dst */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
		if (p->c_func) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
			if (p->c_af == AF_INET6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
				v4compat = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
			if (p->c_parameter == NEXTARG ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
			    p->c_parameter == OPTARG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
				argc--, argv++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
				if (argc == 0 && p->c_parameter == NEXTARG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
					(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
					    "ifconfig: no argument for %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
					    p->c_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
					exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
			 *	Call the function if:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
			 *		there's no address family
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
			 *		restriction
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
			 *	OR
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
			 *		we don't know the address yet
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
			 *		(because we were called from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
			 *		main)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
			 *	OR
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
			 *		there is a restriction AND
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
			 *		the address families match
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
			if ((p->c_af == AF_ANY)	||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
			    (lifrp == (struct lifreq *)NULL) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
			    (lifrp->lifr_addr.ss_family == p->c_af)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
				ret = (*p->c_func)(*argv, p->c_parameter);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
				 *	If c_func failed and we should
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
				 *	abort processing for this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
				 *	interface on failure, return
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
				 *	now rather than going on to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
				 *	process other commands for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
				 *	the same interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
				if (ret != 0 && p->c_abortonfail)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
					return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
		argc--, argv++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
	/* Check to see if there's a security hole in the tunnel setup. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
	tun_reality_check();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
setdebugflag(char *val, int64_t arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
	debug++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
setverboseflag(char *val, int64_t arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
	verbose++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
/*
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   936
 * This function fills in the given lifreq's lifr_addr field based on
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   937
 * g_netmask_set.
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   938
 */
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   939
static void
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   940
set_mask_lifreq(struct lifreq *lifr, struct sockaddr_storage *addr,
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   941
    struct sockaddr_storage *mask)
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   942
{
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   943
	assert(addr != NULL);
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   944
	assert(mask != NULL);
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   945
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   946
	switch (g_netmask_set) {
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   947
	case G_NETMASK_SET:
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   948
		lifr->lifr_addr = g_netmask;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   949
		break;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   950
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   951
	case G_NETMASK_PENDING:
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   952
		/*
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   953
		 * "+" is used as the argument to "netmask" command.  Query
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   954
		 * the database on the correct netmask based on the address to
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   955
		 * be set.
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   956
		 */
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   957
		assert(afp->af_af == AF_INET);
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   958
		g_netmask = *addr;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   959
		if (!in_getmask((struct sockaddr_in *)&g_netmask, _B_TRUE)) {
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   960
			lifr->lifr_addr = *mask;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   961
			g_netmask_set = G_NETMASK_NIL;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   962
		} else {
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   963
			lifr->lifr_addr = g_netmask;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   964
			g_netmask_set = G_NETMASK_SET;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   965
		}
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   966
		break;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   967
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   968
	case G_NETMASK_NIL:
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   969
	default:
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   970
		lifr->lifr_addr = *mask;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   971
		break;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   972
	}
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   973
}
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   974
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
   975
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
 * Set the interface address. Handles <addr>, <addr>/<n> as well as /<n>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
 * syntax for setting the address, the address plus netmask, and just
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
 * the netmask respectively.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
setifaddr(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
	int prefixlen = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
	struct	sockaddr_storage laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
	struct	sockaddr_storage netmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
	struct	sockaddr_in6 *sin6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
	struct	sockaddr_in *sin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
	struct	sockaddr_storage sav_netmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
	if (addr[0] == '/')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
		return (setifprefixlen(addr, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
	(*afp->af_getaddr)(addr, (struct sockaddr *)&laddr, &prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
	(void) memset(&netmask, 0, sizeof (netmask));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
	netmask.ss_family = afp->af_af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	switch (prefixlen) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
	case NO_PREFIX:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
		/* Nothing there - ok */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
	case BAD_ADDR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
		(void) fprintf(stderr, "ifconfig: Bad prefix length in %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
		    addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
		if (afp->af_af == AF_INET6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
			sin6 = (struct sockaddr_in6 *)&netmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
			if (!in_prefixlentomask(prefixlen, ADDRBITS_V6,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
			    (uchar_t *)&sin6->sin6_addr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
				(void) fprintf(stderr, "ifconfig: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
				    "Bad prefix length: %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
				    prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
				exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
			sin = (struct sockaddr_in *)&netmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
			if (!in_prefixlentomask(prefixlen, ADDRBITS_V4,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
			    (uchar_t *)&sin->sin_addr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
				(void) fprintf(stderr, "ifconfig: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
				    "Bad prefix length: %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
				    prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
				exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
		 * Just in case of funny setting of both prefix and netmask,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
		 * prefix should override the netmask command.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
		 */
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1030
		g_netmask_set = G_NETMASK_NIL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
	/* Tell parser that an address was set */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
	setaddr++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
	/* save copy of netmask to restore in case of error */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
	if (ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
		Perror0_exit("SIOCGLIFNETMASK");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
	sav_netmask = lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
	 * Catch set of address for AF_INET6 to perform
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
	 * duplicate address detection. Check that the interface is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
	 * up.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
	if (afp->af_af == AF_INET6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
		if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
			Perror0_exit("ifsetaddr: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
		if (lifr.lifr_flags & IFF_UP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
			if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
				(void) printf(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
				    "setifaddr: Calling ifdad flags %llx\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
				    lifr.lifr_flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
			if (ifdad(name, (struct sockaddr_in6 *)&laddr) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
				exit(3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
	 * If setting the address and not the mask, clear any existing mask
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
	 * and the kernel will then assign the default (netmask has been set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
	 * to 0 in this case).  If setting both (either by using a prefix or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
	 * using the netmask command), set the mask first, so the address will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
	 * be interpreted correctly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
	 */
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1067
	set_mask_lifreq(&lifr, &laddr, &netmask);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
	if (ioctl(s, SIOCSLIFNETMASK, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
		Perror0_exit("SIOCSLIFNETMASK");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
	if (debug) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
		char abuf[INET6_ADDRSTRLEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
		void *addr = (afp->af_af == AF_INET) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
		    (void *)&((struct sockaddr_in *)&laddr)->sin_addr :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
		    (void *)&((struct sockaddr_in6 *)&laddr)->sin6_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
		(void) printf("Setting %s af %d addr %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
		    lifr.lifr_name, afp->af_af,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
		    inet_ntop(afp->af_af, addr, abuf, sizeof (abuf)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
	lifr.lifr_addr = laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
	lifr.lifr_addr.ss_family = afp->af_af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
	if (ioctl(s, SIOCSLIFADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
		 * Restore the netmask
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
		int saverr = errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
		lifr.lifr_addr = sav_netmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
		(void) ioctl(s, SIOCSLIFNETMASK, (caddr_t)&lifr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
		errno = saverr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
		Perror0_exit("SIOCSLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
 * The following functions are stolen from the ipseckey(1m) program.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
 * Perhaps they should be somewhere common, but for now, we just maintain
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
 * two versions.  We do this because of the different semantics for which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
 * algorithms we select ("requested" for ifconfig vs. "actual" for key).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
static ulong_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
parsenum(char *num)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
	ulong_t rc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
	char *end = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
	errno = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
	rc = strtoul(num, &end, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
	if (errno != 0 || end == num || *end != '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
		rc = (ulong_t)-1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
	return (rc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
 * Parse and reverse parse possible algorithm values, include numbers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
 * Mostly stolen from ipseckey.c. See the comments above parsenum() for why
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
 * this isn't common to ipseckey.c.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
 * NOTE: Static buffer in this function for the return value.  Since ifconfig
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
 *	 isn't multithreaded, this isn't a huge problem.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
#define	NBUF_SIZE 20	/* Enough to print a large integer. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
static char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
rparsealg(uint8_t alg_value, int proto_num)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
	struct ipsecalgent *alg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
	static char numprint[128];	/* Enough to hold an algorithm name. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
	/* Special-case 0 to return "<any-none>" */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
	if (alg_value == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
		return ("<any-none>");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
	alg = getipsecalgbynum(alg_value, proto_num, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
	if (alg != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
		(void) strlcpy(numprint, alg->a_names[0], sizeof (numprint));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
		freeipsecalgent(alg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
		(void) snprintf(numprint, sizeof (numprint), "%d", alg_value);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
	return (numprint);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
static uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
parsealg(char *algname, int proto_num)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
	struct ipsecalgent *alg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
	ulong_t invalue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
	if (algname == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
		(void) fprintf(stderr, "ifconfig: Unexpected end of command "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
		    "line.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
	 * Special-case "none". Use strcasecmp because its length is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
	 * bound.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
	if (strcasecmp("none", algname) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
		return ((proto_num == IPSEC_PROTO_ESP) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
		    NO_ESP_EALG : NO_ESP_AALG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
	alg = getipsecalgbyname(algname, proto_num, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
	if (alg != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
		invalue = alg->a_alg_num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
		freeipsecalgent(alg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
		return ((uint_t)invalue);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
	 * Since algorithms can be loaded during kernel run-time, check for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
	 * numeric algorithm values too.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
	invalue = parsenum(algname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
	if ((invalue & (ulong_t)0xff) == invalue)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
		return ((uint_t)invalue);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
	(void) fprintf(stderr, "ifconfig: %s algorithm type %s unknown.\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
	    (proto_num == IPSEC_PROTO_ESP) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
	    "Encryption" : "Authentication", algname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
	exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
	/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
 * Actual ifconfig functions to set tunnel security properties.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
enum ipsec_alg_type { ESP_ENCR_ALG = 1, ESP_AUTH_ALG, AH_AUTH_ALG };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
boolean_t first_set_tun = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
boolean_t encr_alg_set = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
set_tun_algs(int which_alg, int alg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
	struct iftun_req treq;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
	ipsec_req_t *ipsr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
	(void) strncpy(treq.ifta_lifr_name, name, sizeof (treq.ifta_lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
	if (strchr(name, ':') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
		errno = EPERM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
		Perror0_exit("Tunnel params on logical interfaces");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
	if (ioctl(s, SIOCGTUNPARAM, (caddr_t)&treq) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
		if (errno == EOPNOTSUPP || errno == EINVAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
			Perror0_exit("Not a tunnel");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
		else Perror0_exit("SIOCGTUNPARAM");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
	ipsr = (ipsec_req_t *)&treq.ifta_secinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
	if (treq.ifta_vers != IFTUN_VERSION) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
		    "Kernel tunnel secinfo version mismatch.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
	 * If I'm just starting off this ifconfig, I want a clean slate,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
	 * otherwise, I've captured the current tunnel security settings.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
	 * In the case of continuation, I merely add to the settings.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
	if (first_set_tun) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
		first_set_tun = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
		(void) memset(ipsr, 0, sizeof (*ipsr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
	treq.ifta_flags = IFTUN_SECURITY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
	switch (which_alg) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
	case ESP_ENCR_ALG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
		if (alg == NO_ESP_EALG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
			if (ipsr->ipsr_esp_auth_alg == SADB_AALG_NONE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
				ipsr->ipsr_esp_req = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
			ipsr->ipsr_esp_alg = SADB_EALG_NONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
			encr_alg_set = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
			ipsr->ipsr_esp_req =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
			    IPSEC_PREF_REQUIRED | IPSEC_PREF_UNIQUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
			ipsr->ipsr_esp_alg = alg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
	case ESP_AUTH_ALG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
		if (alg == NO_ESP_AALG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
			if (ipsr->ipsr_esp_alg == SADB_EALG_NONE ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
			    ipsr->ipsr_esp_alg == SADB_EALG_NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
				ipsr->ipsr_esp_req = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
			ipsr->ipsr_esp_auth_alg = SADB_AALG_NONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
			ipsr->ipsr_esp_req =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
			    IPSEC_PREF_REQUIRED | IPSEC_PREF_UNIQUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
			ipsr->ipsr_esp_auth_alg = alg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
			/* Let the user specify NULL encryption implicitly. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
			if (ipsr->ipsr_esp_alg == SADB_EALG_NONE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
			    !encr_alg_set)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
				ipsr->ipsr_esp_alg = SADB_EALG_NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
	case AH_AUTH_ALG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
		if (alg == NO_AH_AALG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
			ipsr->ipsr_ah_req = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
			ipsr->ipsr_auth_alg = SADB_AALG_NONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
			ipsr->ipsr_ah_req =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
			    IPSEC_PREF_REQUIRED | IPSEC_PREF_UNIQUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
			ipsr->ipsr_auth_alg = alg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
		/* Will never hit DEFAULT */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	if (ioctl(s, SIOCSTUNPARAM, (caddr_t)&treq) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
		Perror2_exit("set tunnel security properties",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
		    treq.ifta_lifr_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
set_tun_esp_encr_alg(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
	return (set_tun_algs(ESP_ENCR_ALG,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
		    parsealg(addr, IPSEC_PROTO_ESP)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
set_tun_esp_auth_alg(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
	return (set_tun_algs(ESP_AUTH_ALG,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
		    parsealg(addr, IPSEC_PROTO_AH)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
set_tun_ah_alg(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
	return (set_tun_algs(AH_AUTH_ALG,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
		    parsealg(addr, IPSEC_PROTO_AH)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
setifrevarp(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
	struct sockaddr_in	laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
	if (afp->af_af == AF_INET6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
		    "ifconfig: revarp not possible on IPv6 interface %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
		    name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
	if (doifrevarp(name, &laddr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
		laddr.sin_family = AF_INET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
		(void) memcpy(&lifr.lifr_addr, &laddr, sizeof (laddr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
		if (ioctl(s, SIOCSLIFADDR, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
			Perror0_exit("SIOCSLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
setifsubnet(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
	int prefixlen = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
	struct	sockaddr_storage subnet;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
	(*afp->af_getaddr)(addr, &subnet, &prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
	switch (prefixlen) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
	case NO_PREFIX:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
		    "ifconfig: Missing prefix length in subnet %s\n", addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
		/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
	case BAD_ADDR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
		    "ifconfig: Bad prefix length in %s\n", addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
	lifr.lifr_addr = subnet;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
	lifr.lifr_addrlen = prefixlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
	if (ioctl(s, SIOCSLIFSUBNET, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
		Perror0_exit("SIOCSLIFSUBNET");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
setifnetmask(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
	struct sockaddr_in netmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
	assert(afp->af_af != AF_INET6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
	if (strcmp(addr, "+") == 0) {
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1380
		if (!in_getmask(&netmask, _B_FALSE))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
			return (0);
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1382
		(void) printf("Setting netmask of %s to %s\n", name,
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1383
		    inet_ntoa(netmask.sin_addr));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
		in_getaddr(addr, (struct sockaddr *)&netmask, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
	(void) memcpy(&lifr.lifr_addr, &netmask, sizeof (netmask));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
	if (ioctl(s, SIOCSLIFNETMASK, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
		Perror0_exit("SIOCSLIFNETMASK");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
 * Parse '/<n>' as a netmask.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
setifprefixlen(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
	int prefixlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
	int af = afp->af_af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
	prefixlen = in_getprefixlen(addr, _B_TRUE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
	    (af == AF_INET) ? ADDRBITS_V4 : ADDRBITS_V6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
	if (prefixlen < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
		    "ifconfig: Bad prefix length in %s\n", addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
	(void) memset(&lifr.lifr_addr, 0, sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
	lifr.lifr_addr.ss_family = af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
	if (af == AF_INET6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
		struct sockaddr_in6 *sin6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
		sin6 = (struct sockaddr_in6 *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
		if (!in_prefixlentomask(prefixlen, ADDRBITS_V6,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
		    (uchar_t *)&sin6->sin6_addr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
			(void) fprintf(stderr, "ifconfig: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
			    "Bad prefix length: %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
			    prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
	} else if (af == AF_INET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
		struct sockaddr_in *sin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
		sin = (struct sockaddr_in *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
		if (!in_prefixlentomask(prefixlen, ADDRBITS_V4,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
		    (uchar_t *)&sin->sin_addr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
			(void) fprintf(stderr, "ifconfig: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
			    "Bad prefix length: %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
			    prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
		(void) fprintf(stderr, "ifconfig: setting prefix only supported"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
		    " for address family inet or inet6\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
	if (ioctl(s, SIOCSLIFNETMASK, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
		Perror0_exit("SIOCSLIFNETMASK");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
setifbroadaddr(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
	struct	sockaddr_in broadaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
	assert(afp->af_af != AF_INET6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
	if (strcmp(addr, "+") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
		 * This doesn't set the broadcast address at all. Rather, it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
		 * gets, then sets the interface's address, relying on the fact
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
		 * that resetting the address will reset the broadcast address.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
		(void) strncpy(lifr.lifr_name, name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
		    sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
		if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
			if (errno != EADDRNOTAVAIL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
				Perror0_exit("SIOCGLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
		if (ioctl(s, SIOCSLIFADDR, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
			Perror0_exit("SIOCGLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
	in_getaddr(addr, (struct sockaddr *)&broadaddr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
	(void) memcpy(&lifr.lifr_addr, &broadaddr, sizeof (broadaddr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
	if (ioctl(s, SIOCSLIFBRDADDR, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
		Perror0_exit("SIOCSLIFBRDADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
 * set interface destination address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
setifdstaddr(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
	(*afp->af_getaddr)(addr, (struct sockaddr *)&lifr.lifr_addr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
	if (ioctl(s, SIOCSLIFDSTADDR, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
		Perror0_exit("setifdstaddr: SIOCSLIFDSTADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
setifflags(char *val, int64_t value)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
	int phyintlen, origphyintlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
	if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
		Perror0_exit("setifflags: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
	if (value == IFF_NOFAILOVER) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
		 * Fail if '-failover' is set after a prior addif created the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
		 * alias on a different interface. This can happen when the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
		 * interface is part of an IPMP group.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
		phyintlen = strcspn(name, ":");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
		origphyintlen = strcspn(origname, ":");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
		if (phyintlen != origphyintlen ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
		    strncmp(name, origname, phyintlen) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
			(void) fprintf(stderr, "ifconfig: can't set -failover "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
			    "on failed/standby/offlined interface %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
			    origname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
	 * Catch "up" transition for AF_INET6 to perform duplicate address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
	 * detection. ifdad checks if an address has been set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
	if (afp->af_af == AF_INET6 && !(lifr.lifr_flags & IFF_UP) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
	    value == IFF_UP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
		if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
			(void) printf(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
			    "setifaddr:Calling ifdad flags %llx value 0x%llx\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
			    lifr.lifr_flags, value);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
		if (ifdad(name, NULL) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
	if (value < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
		value = -value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
		lifr.lifr_flags &= ~value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
		lifr.lifr_flags |= value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
	if (ioctl(s, SIOCSLIFFLAGS, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
		Perror0_exit("setifflags: SIOCSLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
setifmetric(char *val, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
	lifr.lifr_metric = atoi(val);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
	if (ioctl(s, SIOCSLIFMETRIC, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
		Perror0_exit("setifmetric: SIOCSLIFMETRIC");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
setifmtu(char *val, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
	lifr.lifr_mtu = atoi(val);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
	if (ioctl(s, SIOCSLIFMTU, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
		Perror0_exit("setifmtu: SIOCSLIFMTU");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
setifindex(char *val, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
	lifr.lifr_index = atoi(val);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
	if (ioctl(s, SIOCSLIFINDEX, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
		Perror0_exit("setifindex: SIOCSLIFINDEX");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
setifether(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
	uchar_t	*ea;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
	iface_t	*current;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
	int	maclen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
	if (addr == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
		ifstatus(name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
		print_ifether(name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
	phyif = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
	logifs = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
	 * if the IP interface in the arguments is a logical
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
	 * interface, exit with an error now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
	if (strchr(name, ':') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
		(void) fprintf(stderr, "ifconfig: cannot change"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
		    " ethernet address of a logical interface\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	ea = _link_aton(addr, &maclen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
	if (ea == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
		if (maclen == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
			(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
			    "ifconfig: %s: bad address\n", addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
			(void) fprintf(stderr, "ifconfig: malloc() failed\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
	(void) strncpy(savedname, name, sizeof (savedname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
	 * Call selectifs only for the IP interfaces that are ipv4.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
	 * offflags == IFF_IPV6 because you should not change the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
	 *		Ethernet address of an ipv6 interface
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
	foreachinterface(selectifs, 0, (char **)NULL, 0, 0, IFF_IPV6, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
	/* If physical interface not found, exit now */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
	if (phyif == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
		    "ifconfig: interface %s not found\n", savedname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
	/* Restore */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
	(void) strncpy(name, savedname, sizeof (name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
	(void) strncpy(origname, savedname, sizeof (origname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
	 * close and reopen the socket
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
	 * we don't know which type of socket we have now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
	(void) close(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
	s = socket(SOCKET_AF(AF_UNSPEC), SOCK_DGRAM, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
	if (s < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
		Perror0_exit("socket");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
	 * mark down the logical interfaces first,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
	 * and then the physical interface
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
	if (updownifs(logifs, 0) < 0 || updownifs(phyif, 0) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
		Perror0_exit("mark down interface failed");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
	 * Change the physical address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
	if (dlpi_set_address(savedname, ea, maclen) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
		    "ifconfig: failed setting mac address on %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
		    savedname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
	 * if any interfaces were marked down before changing the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
	 * ethernet address, put them up again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
	 * First the physical interface, then the logical ones.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
	if (updownifs(phyif, 1) < 0 || updownifs(logifs, 1) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
		Perror0_exit("mark down interface failed");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
	/* Free the memory allocated by selectifs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
	free(phyif);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
	for (current = logifs; current != NULL; current = logifs) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
		logifs = logifs->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
		free(current);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
 * Print an interface's Ethernet address, if it has one.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
print_ifether(char *ifname)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
	int		protocol;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
	icfg_if_t	interface;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
	icfg_handle_t	handle;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
	int		fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
	 * Loopback interfaces and tunnels can't have MAC addresses,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
	 * so filter them out first.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
	if (strcmp(ifname, LOOPBACK_IF) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
	fd = socket(AF_INET, SOCK_DGRAM, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
	if (fd == -1 || ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
		 * It's possible the interface is only configured for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
		 * IPv6; check again with AF_INET6.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
		(void) close(fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
		fd = socket(AF_INET6, SOCK_DGRAM, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
		if (fd == -1 || ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
			(void) close(fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
	(void) close(fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
	/* Virtual interfaces don't have MAC addresses */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
	if (lifr.lifr_flags & IFF_VIRTUAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
	 * We must be careful to set if_protocol based on the current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1726
	 * properties of the interface.  For instance, if "ip.tun0" is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1727
	 * configured only as an IPv6 tunnel, then if_protocol must be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
	 * set to AF_INET6 or icfg_get_tunnel_lower() will fail and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
	 * we will falsely conclude that it's not a tunnel.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
	interface.if_protocol = AF_INET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
	if (lifr.lifr_flags & IFF_IPV6)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
		interface.if_protocol = AF_INET6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
	(void) strncpy(interface.if_name, ifname, sizeof (interface.if_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
	if (icfg_open(&handle, &interface) == ICFG_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
		if (icfg_get_tunnel_lower(handle, &protocol) == ICFG_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
			/* Tunnel op succeeded -- it's a tunnel so skip */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
			icfg_close(handle);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
		icfg_close(handle);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
	dlpi_print_address(ifname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
 * static void selectifs(int argc, char *argv[], int af, struct lifreq *rp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
 * Called inside setifether() to create a list of interfaces to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
 * mark down/up when changing the Ethernet address.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
 * If the current interface is the physical interface passed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
 * as an argument to ifconfig, update phyif.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
 * If the current interface is a logical interface associated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
 * to the physical interface, add it to the logifs list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
selectifs(int argc, char *argv[], int af, struct lifreq *rp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
	char		*colonp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
	int		length;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
	iface_t		*current;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
	 *  savedname=	name of the IP interface to which you want to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
	 *		change ethernet address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
	 *  name=	name of the current IP interface
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
	colonp = strchr(name, ':');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
	if (colonp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
		length = max(strlen(savedname), strlen(name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
		length = max(strlen(savedname), colonp - name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
	if (strncmp(savedname, name, length) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
		(void) strcpy(lifr.lifr_name, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
		if (ioctl(s, SIOCGLIFFLAGS, &lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
			Perror0("selectifs: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
		if ((current = malloc(sizeof (iface_t))) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
			Perror0_exit("selectifs: malloc failed\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
		if (colonp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
			/* this is the physical interface */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
			phyif = current;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
			bcopy(&lifr, &phyif->lifr, sizeof (struct lifreq));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
			phyif->next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
			/* this is a logical interface */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
			bcopy(&lifr, &current->lifr, sizeof (struct lifreq));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
			current->next = logifs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
			logifs = current;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
 * static int updownifs(iface_t *ifs, int up)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
 * It takes in input a list of IP interfaces (ifs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
 * and a flag (up).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
 * It marks each interface in the list down (up = 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
 * or up (up > 0). This is done ONLY if the IP
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
 * interface was originally up.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
 * Return values:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
 *  0 = everything OK
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
 * -1 = problem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
updownifs(iface_t *ifs, int up)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
	iface_t *current;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
	int	ret = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
	int 	save_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
	char	savename[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
	uint64_t orig_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
	for (current = ifs; current != NULL; current = current->next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
		if (current->lifr.lifr_flags & IFF_UP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
			orig_flags = current->lifr.lifr_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
			if (!up)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
				current->lifr.lifr_flags &= ~IFF_UP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
			if (ioctl(s, SIOCSLIFFLAGS, &current->lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
				save_errno = errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
				(void) strcpy(savename,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
				    current->lifr.lifr_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
				ret = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
			if (!up) /* restore the original flags */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
				current->lifr.lifr_flags = orig_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
	if (ret == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
		(void) strcpy(lifr.lifr_name, savename);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
		errno = save_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
 * Create the next unused logical interface using the original name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
 * and assign the address (and mask if '/<n>' is part of the address).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
 * Use the new logical interface for subsequent subcommands by updating
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
 * the name variable.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
 * This allows syntax like:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
 *	ifconfig le0 addif 109.106.86.130 netmask + up \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
 *	addif 109.106.86.131 netmask + up
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
addif(char *str, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
	int prefixlen = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
	struct sockaddr_storage laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
	struct sockaddr_storage mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
	(void) strncpy(name, origname, sizeof (name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
	if (strchr(name, ':') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
		    "ifconfig: addif: bad physical interface name %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
		    name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
	 * clear so parser will interpret next address as source followed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
	 * by possible dest
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
	setaddr = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
	(*afp->af_getaddr)(str, (struct sockaddr *)&laddr, &prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1881
	switch (prefixlen) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
	case NO_PREFIX:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
		/* Nothing there - ok */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
	case BAD_ADDR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
		    "ifconfig: Bad prefix length in %s\n", str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1889
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
		(void) memset(&mask, 0, sizeof (mask));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
		mask.ss_family = afp->af_af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
		if (afp->af_af == AF_INET6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
			struct sockaddr_in6 *sin6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
			sin6 = (struct sockaddr_in6 *)&mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
			if (!in_prefixlentomask(prefixlen, ADDRBITS_V6,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
			    (uchar_t *)&sin6->sin6_addr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
				(void) fprintf(stderr, "ifconfig: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
				    "Bad prefix length: %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
				    prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
				exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
			struct sockaddr_in *sin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
			sin = (struct sockaddr_in *)&mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
			if (!in_prefixlentomask(prefixlen, ADDRBITS_V4,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
			    (uchar_t *)&sin->sin_addr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
				(void) fprintf(stderr, "ifconfig: "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
				    "Bad prefix length: %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1910
				    prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
				exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
		}
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1914
		g_netmask_set = G_NETMASK_NIL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1918
	/*
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1919
	 * This is a "hack" to get around the problem of SIOCLIFADDIF.  The
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1920
	 * problem is that this ioctl does not include the netmask when
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1921
	 * adding a logical interface.  This is the same problem described
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1922
	 * in the ifconfig() comments.  To get around this problem, we first
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1923
	 * add the logical interface with a 0 address.  After that, we set
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1924
	 * the netmask if provided.  Finally we set the interface address.
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1925
	 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1927
	(void) memset(&lifr.lifr_addr, 0, sizeof (lifr.lifr_addr));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
	/* Note: no need to do DAD here since the interface isn't up yet. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
	if (ioctl(s, SIOCLIFADDIF, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
		Perror0_exit("addif: SIOCLIFADDIF");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
	(void) printf("Created new logical interface %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
	    lifr.lifr_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
	(void) strncpy(name, lifr.lifr_name, sizeof (name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1938
	/*
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1939
	 * Check and see if any "netmask" command is used and perform the
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1940
	 * necessary operation.
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1941
	 */
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1942
	set_mask_lifreq(&lifr, &laddr, &mask);
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1943
	/*
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1944
	 * Only set the netmask if "netmask" command is used or a prefix is
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1945
	 * provided.
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1946
	 */
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1947
	if (g_netmask_set == G_NETMASK_SET || prefixlen >= 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
		if (ioctl(s, SIOCSLIFNETMASK, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
			Perror0_exit("addif: SIOCSLIFNETMASK");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
	}
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1951
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1952
	/* Finally, we set the interface address. */
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1953
	lifr.lifr_addr = laddr;
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1954
	if (ioctl(s, SIOCSLIFADDR, (caddr_t)&lifr) < 0)
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1955
		Perror0_exit("SIOCSLIFADDR");
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  1956
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
	 * let parser know we got a source.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
	 * Next address, if given, should be dest
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
	setaddr++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
 * Remove a logical interface based on its IP address. Unlike addif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
 * there is no '/<n>' here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
 * Verifies that the interface is down before it is removed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
removeif(char *str, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
	struct sockaddr_storage laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
	if (strchr(name, ':') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
		    "ifconfig: removeif: bad physical interface name %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
		    name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
	(*afp->af_getaddr)(str, &laddr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
	lifr.lifr_addr = laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
	if (ioctl(s, SIOCLIFREMOVEIF, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
		if (errno == EBUSY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
			/* This can only happen if ipif_id = 0 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
			(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
			    "ifconfig: removeif: can't remove interface: %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
			    name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
		Perror0_exit("removeif: SIOCLIFREMOVEIF");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
 * If laddr is non-NULL it is used - otherwise we use the address on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
 * the interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
ifdad(char *ifname, struct sockaddr_in6 *laddr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
	struct sockaddr_in6 testaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
	struct lifreq lifr2;	/* Avoid overriting lifr */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
		(void) printf("ifdad(%s)\n", ifname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
	assert(afp->af_af == AF_INET6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
	 * Check the address assigned to the interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
	 * Skip the check if IFF_NOLOCAL, IFF_NONUD, IFF_ANYCAST, or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
	 * IFF_LOOPBACK.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
	 * Note that IFF_NONUD turns of both NUD and DAD.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
	(void) strncpy(lifr2.lifr_name, ifname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
	    sizeof (lifr2.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
	if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr2) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
		Perror0_exit("ifdad: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
	if (lifr2.lifr_flags & (IFF_NOLOCAL|IFF_LOOPBACK|IFF_NONUD|IFF_ANYCAST))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
	if (laddr != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
		testaddr = *laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
		if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr2) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
			Perror0_exit("ifdad: SIOCGLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
		testaddr = *(struct sockaddr_in6 *)&lifr2.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
	if (IN6_IS_ADDR_UNSPECIFIED(&testaddr.sin6_addr))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
	if (do_dad(name, &testaddr) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
 * Set the address token for IPv6.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
setiftoken(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
	int prefixlen = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
	struct sockaddr_in6 token;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
	in6_getaddr(addr, (struct sockaddr *)&token, &prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
	switch (prefixlen) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
	case NO_PREFIX:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
		    "ifconfig: Missing prefix length in subnet %s\n", addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
		/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
	case BAD_ADDR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
		    "ifconfig: Bad prefix length in %s\n", addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
	(void) memcpy(&lifr.lifr_addr, &token, sizeof (token));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
	lifr.lifr_addrlen = prefixlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
	if (ioctl(s, SIOCSLIFTOKEN, (caddr_t)&lifr) < 0)  {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
		Perror0_exit("setiftoken: SIOCSLIFTOKEN");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2081
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
 * Return value: 0 on success, -1 on failure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
connect_to_mpathd(int family)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
	int s;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
	struct sockaddr_storage ss;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
	struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
	struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
	int addrlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
	int ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
	int on;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
	s = socket(family, SOCK_STREAM, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
	if (s < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
		Perror0_exit("connect_to_mpathd: socket");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
	(void) bzero((char *)&ss, sizeof (ss));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
	ss.ss_family = family;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
	 * Need to bind to a privileged port. For non-root, this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
	 * will fail. in.mpathd verifies that only commands coming
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
	 * from privileged ports succeed so that ordinary users
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
	 * can't connect and start talking to in.mpathd
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
	on = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
	if (setsockopt(s, IPPROTO_TCP, TCP_ANONPRIVBIND, &on,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
	    sizeof (on)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
		Perror0_exit("connect_to_mpathd: setsockopt");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
	switch (family) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
	case AF_INET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
		sin->sin_port = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
		sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
		addrlen = sizeof (struct sockaddr_in);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
	case AF_INET6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
		sin6->sin6_port = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
		sin6->sin6_addr = loopback_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
		addrlen = sizeof (struct sockaddr_in6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
	ret = bind(s, (struct sockaddr *)&ss, addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
	if (ret != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
		(void) close(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
	switch (family) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
	case AF_INET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
		sin->sin_port = htons(MPATHD_PORT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
	case AF_INET6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
		sin6->sin6_port = htons(MPATHD_PORT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
	ret = connect(s, (struct sockaddr *)&ss, addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
	(void) close(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
setifgroupname(char *grpname, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
	if (debug) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
		(void) printf("Setting groupname %s on interface %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
		    grpname, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
	(void) strncpy(lifr.lifr_groupname, grpname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
	    sizeof (lifr.lifr_groupname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
	if (ioctl(s, SIOCSLIFGROUPNAME, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
		Perror0_exit("setifgroupname: SIOCSLIFGROUPNAME");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
	 * If the SUNW_NO_MPATHD environment variable is set then don't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
	 * bother starting up in.mpathd.  See PSARC/2002/249 for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
	 * depressing details on this bit of stupidity.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
	if (getenv("SUNW_NO_MPATHD") != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
	 * Try to connect to in.mpathd using IPv4. If we succeed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
	 * we conclude that in.mpathd is running, and quit.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
	if (connect_to_mpathd(AF_INET) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
		/* connect succeeded, mpathd is already running */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
	 * Try to connect to in.mpathd using IPv6. If we succeed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
	 * we conclude that in.mpathd is running, and quit.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
	if (connect_to_mpathd(AF_INET6) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
		/* connect succeeded, mpathd is already running */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
	 * in.mpathd may not be running. Start it now. If it is already
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
	 * running, in.mpathd will take care of handling multiple incarnations
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
	 * of itself. ifconfig only tries to optimize performance by not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
	 * starting another incarnation of in.mpathd.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
	switch (fork()) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
	case -1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
		Perror0_exit("setifgroupname: fork");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
		/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
	case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
		(void) execl(MPATHD_PATH, MPATHD_PATH, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
		_exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
		/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
 * To list all the modules above a given network interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
modlist(char *null, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
	int muxfd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
	int ipfd_lowstr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
	int arpfd_lowstr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
	int num_mods;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
	struct str_list strlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
	int orig_arpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
	if (ip_domux2fd(&muxfd, &ipfd_lowstr, &arpfd_lowstr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
	    &orig_arpid) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
	if ((num_mods = ioctl(ipfd_lowstr, I_LIST, NULL)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
		Perror0("cannot I_LIST to get the number of modules");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
		if (debug > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
			(void) printf("Listing (%d) modules above %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
			    num_mods, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
		strlist.sl_nmods = num_mods;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
		strlist.sl_modlist = malloc(sizeof (struct str_mlist) *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
		    num_mods);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
		if (strlist.sl_modlist == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
			Perror0("cannot malloc");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
			if (ioctl(ipfd_lowstr, I_LIST, (caddr_t)&strlist) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
				Perror0("cannot I_LIST for module names");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
				for (i = 0; i < strlist.sl_nmods; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
				    (void) printf("%d %s\n", i,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
				    strlist.sl_modlist[i].l_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
			free(strlist.sl_modlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
	return (ip_plink(muxfd, ipfd_lowstr, arpfd_lowstr, orig_arpid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
#define	MODINSERT_OP	'i'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
#define	MODREMOVE_OP	'r'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
 * To insert a module to the stream of the interface.  It is just a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
 * wrapper.  The real function is modop().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
modinsert(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
	return (modop(arg, MODINSERT_OP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
 * To remove a module from the stream of the interface.  It is just a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
 * wrapper.  The real function is modop().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
modremove(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
	return (modop(arg, MODREMOVE_OP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
 * Open a stream on /dev/udp, pop off all undesired modules (note that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
 * the user may have configured autopush to add modules above or below
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
 * udp), and push the arp module onto raw IP.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
open_arp_on_udp(char *udp_dev_name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
	int fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
	boolean_t popped;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
	if ((fd = open(udp_dev_name, O_RDWR)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
		Perror2("open", udp_dev_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
	errno = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
	popped = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
	while (ioctl(fd, I_POP, 0) != -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
		popped = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
	if (!popped) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
		Perror2("cannot pop", udp_dev_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
	} else if (errno != EINVAL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
		Perror2("pop", udp_dev_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
	} else if (ioctl(fd, I_PUSH, ARP_MOD_NAME) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
		Perror2("arp PUSH", udp_dev_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
		return (fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
	(void) close(fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
	return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
 * Helper function for mod*() functions.  It gets a fd to the lower IP
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
 * stream and I_PUNLINK's the lower stream.  It also initializes the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
 * global variable lifr.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
 * Param:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
 *	int *udp_fd: (referenced) fd to /dev/udp (upper IP stream).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
 *	int *fd: (referenced) fd to the lower IP stream.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
 * Return:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
 *	-1 if operation fails, 0 otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
 * Please see the big block comment above plumb_one_device()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
 * for the logic of the PLINK/PUNLINK
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
ip_domux2fd(int *muxfd, int *ipfd_lowstr, int *arpfd_lowstr, int *orig_arpid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
	int		ip_fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
	uint64_t	flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
	char		*udp_dev_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
	char		*ip_dev_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
	*orig_arpid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
	if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
		Perror0_exit("status: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
	flags = lifr.lifr_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
	if (flags & IFF_IPV4) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
		udp_dev_name = UDP_DEV_NAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
		ip_dev_name  = IP_DEV_NAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
	} else if (flags & IFF_IPV6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
		udp_dev_name = UDP6_DEV_NAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
		ip_dev_name  = IP6_DEV_NAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
	if ((ip_fd = open(ip_dev_name, O_RDWR)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
		Perror2("open", ip_dev_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
	if (ioctl(ip_fd, SIOCGLIFMUXID, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
		Perror2("SIOCGLIFMUXID", ip_dev_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2358
	if (debug > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
		(void) printf("ARP_muxid %d IP_muxid %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2360
		    lifr.lifr_arp_muxid, lifr.lifr_ip_muxid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2362
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
	if ((*muxfd = open_arp_on_udp(udp_dev_name)) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2366
	if (lifr.lifr_arp_muxid != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2367
		if ((*arpfd_lowstr = ioctl(*muxfd, _I_MUXID2FD,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2368
		    lifr.lifr_arp_muxid)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
			if ((errno == EINVAL) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2370
			    (flags & (IFF_NOARP | IFF_IPV6))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2371
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
				 * Some plumbing utilities set the muxid to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
				 * -1 or some invalid value to signify that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
				 * there is no arp stream. Set the muxid to 0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
				 * before trying to unplumb the IP stream.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
				 * IP does not allow the IP stream to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
				 * unplumbed if it sees a non-null arp muxid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
				 * for consistency of IP-ARP streams.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
				*orig_arpid = lifr.lifr_arp_muxid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
				lifr.lifr_arp_muxid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
				(void) ioctl(*muxfd, SIOCSLIFMUXID,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
				    (caddr_t)&lifr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
				*arpfd_lowstr = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
				Perror0("_I_MUXID2FD");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
		} else if (ioctl(*muxfd, I_PUNLINK,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
		    lifr.lifr_arp_muxid) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
			Perror2("I_PUNLINK", udp_dev_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
		*arpfd_lowstr = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
	if ((*ipfd_lowstr = ioctl(*muxfd, _I_MUXID2FD,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
	    lifr.lifr_ip_muxid)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
		Perror0("_I_MUXID2FD");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
		/* Undo any changes we made */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
		if (*orig_arpid != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
			lifr.lifr_arp_muxid = *orig_arpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
			(void) ioctl(*muxfd, SIOCSLIFMUXID, (caddr_t)&lifr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
	if (ioctl(*muxfd, I_PUNLINK, lifr.lifr_ip_muxid) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
		Perror2("I_PUNLINK", udp_dev_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
		/* Undo any changes we made */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
		if (*orig_arpid != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
			lifr.lifr_arp_muxid = *orig_arpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
			(void) ioctl(*muxfd, SIOCSLIFMUXID, (caddr_t)&lifr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
 * Helper function for mod*() functions.  It I_PLINK's back the upper and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
 * lower IP streams.  Note that this function must be called after
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
 * ip_domux2fd().  In ip_domux2fd(), the global variable lifr is initialized
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
 * and ip_plink() needs information in lifr.  So ip_domux2fd() and ip_plink()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
 * must be called in pairs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
 * Param:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
 *	int udp_fd: fd to /dev/udp (upper IP stream).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
 *	int fd: fd to the lower IP stream.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
 * Return:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
 *	-1 if operation fails, 0 otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
 * Please see the big block comment above plumb_one_device()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
 * for the logic of the PLINK/PUNLINK
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
ip_plink(int muxfd, int ipfd_lowstr, int arpfd_lowstr, int orig_arpid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
	int ip_muxid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
	ip_muxid = ioctl(muxfd, I_PLINK, ipfd_lowstr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
	if (ip_muxid < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
		Perror2("I_PLINK", UDP_DEV_NAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2446
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
	 * If there is an arp stream, plink it. If there is no
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
	 * arp stream, then it is possible that the plumbing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
	 * utility could have stored any value in the arp_muxid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
	 * If so, restore it from orig_arpid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
	if (arpfd_lowstr != -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
		if (ioctl(muxfd, I_PLINK, arpfd_lowstr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
			Perror2("I_PLINK", UDP_DEV_NAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2458
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
	} else if (orig_arpid != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
		/* Undo the changes we did in ip_domux2fd */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
		lifr.lifr_arp_muxid = orig_arpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
		lifr.lifr_ip_muxid = ip_muxid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2463
		(void) ioctl(muxfd, SIOCSLIFMUXID, (caddr_t)&lifr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2468
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2471
 * The names of other core TCP/IP stack modules which cannot be removed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
#ifndef	TUN_NAME
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2474
#define	TUN_NAME	"tun"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
#ifndef	ATUN_NAME
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
#define	ATUN_NAME	"atun"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2480
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
#ifndef	TUN6TO4_NAME
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2482
#define	TUN6TO4_NAME	"6to4tun"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
 * The real function to perform module insertion/removal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
 * Param:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
 *	char *arg: the argument string module_name@position
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
 *	char op: operation, either MODINSERT_OP or MODREMOVE_OP.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
 * Return:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
 *	Before doing ip_domux2fd(), this function calls exit(1) in case of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
 *	error.  After ip_domux2fd() is done, it returns -1 for error, 0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
 *	otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
modop(char *arg, char op)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
	char *pos_p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
	int muxfd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2502
	int ipfd_lowstr;  /* IP stream (lower stream of mux) to be plinked */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2503
	int arpfd_lowstr; /* ARP stream (lower stream of mux) to be plinked */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2504
	struct strmodconf mod;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2505
	char *at_char = "@";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2506
	char *arg_str;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2507
	int orig_arpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2511
	/* Need to save the original string for -a option. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2512
	if ((arg_str = malloc(strlen(arg) + 1)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2513
		Perror0("cannot malloc");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
	(void) strcpy(arg_str, arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
	if (*arg_str == *at_char) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2520
		    "ifconfig: must supply a module name\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2521
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2522
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2523
	mod.mod_name = strtok(arg_str, at_char);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
	if (strlen(mod.mod_name) > FMNAMESZ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2525
		(void) fprintf(stderr, "ifconfig: module name too long: %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2526
		    mod.mod_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2527
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2530
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2531
	 * Need to make sure that the core TCP/IP stack modules are not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2532
	 * removed.  Otherwise, "bad" things can happen.  If a module
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2533
	 * is removed and inserted back, it loses its old state.  But
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2534
	 * the modules above it still have the old state.  E.g. IP assumes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2535
	 * fast data path while tunnel after re-inserted assumes that it can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2536
	 * receive M_DATA only in fast data path for which it does not have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2537
	 * any state.  This is a general caveat of _I_REMOVE/_I_INSERT.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
	if (op == MODREMOVE_OP &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2540
	    (strcmp(mod.mod_name, ARP_MOD_NAME) == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2541
	    strcmp(mod.mod_name, IP_MOD_NAME) == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2542
	    strcmp(mod.mod_name, TUN_NAME) == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2543
	    strcmp(mod.mod_name, ATUN_NAME) == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
	    strcmp(mod.mod_name, TUN6TO4_NAME) == 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2545
		(void) fprintf(stderr, "ifconfig: cannot remove %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2546
		    mod.mod_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2547
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
	if ((pos_p = strtok(NULL, at_char)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
		(void) fprintf(stderr, "ifconfig: must supply a position\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
	mod.pos = atoi(pos_p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
	if (ip_domux2fd(&muxfd, &ipfd_lowstr, &arpfd_lowstr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
	    &orig_arpid) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
		free(arg_str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
	switch (op) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
	case MODINSERT_OP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
		if (debug > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
			(void) printf("Inserting module %s at %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
			    mod.mod_name, mod.pos);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
		if (ioctl(ipfd_lowstr, _I_INSERT, (caddr_t)&mod) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
			Perror2("fail to insert module", mod.mod_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
	case MODREMOVE_OP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
		if (debug > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
			(void) printf("Removing module %s at %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
			    mod.mod_name, mod.pos);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
		if (ioctl(ipfd_lowstr, _I_REMOVE, (caddr_t)&mod) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
			Perror2("fail to remove module", mod.mod_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
		/* Should never get to here. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
		(void) fprintf(stderr, "Unknown operation\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
	free(arg_str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
	return (ip_plink(muxfd, ipfd_lowstr, arpfd_lowstr, orig_arpid));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2587
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2588
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2589
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2591
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2592
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2593
getnd(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2594
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2595
	struct sockaddr_in6 v6addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
	char *str = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
	in6_getaddr(addr, &v6addr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
	(void) memcpy(&lifr.lifr_nd.lnr_addr, &v6addr, sizeof (v6addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
	if (ioctl(s, SIOCLIFGETND, (caddr_t)&lifr) < 0)  {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
		Perror0_exit("SIOCLIFGETND");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
	str = _link_ntoa((const unsigned char *)lifr.lifr_nd.lnr_hdw_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
	    str, lifr.lifr_nd.lnr_hdw_len, IFT_OTHER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
	if (str != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
		(void) printf("address %s", str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
		free(str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
	(void) printf(" state %d/%d/%d flags %x\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
		lifr.lifr_nd.lnr_state_create,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
		lifr.lifr_nd.lnr_state_same_lla,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
		lifr.lifr_nd.lnr_state_diff_lla,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
		lifr.lifr_nd.lnr_flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
delnd(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
	struct sockaddr_in6 v6addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
	in6_getaddr(addr, &v6addr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
	(void) memcpy(&lifr.lifr_nd.lnr_addr, &v6addr, sizeof (v6addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
	lifr.lifr_nd.lnr_state_create = ND_UNCHANGED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
	lifr.lifr_nd.lnr_state_same_lla = ND_UNCHANGED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
	lifr.lifr_nd.lnr_state_diff_lla = ND_UNCHANGED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
	lifr.lifr_nd.lnr_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
	if (ioctl(s, SIOCLIFDELND, (caddr_t)&lifr) < 0)  {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2633
		Perror0_exit("SIOCLIFDELND");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2634
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
setnd(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
	struct sockaddr_in6 v6addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
	 * XXX parse phyaddr? Need syntax to fit in one argv.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
	 * XXX <proto addr>/<phyaddr> ??
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
	in6_getaddr(addr, &v6addr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2649
	(void) memcpy(&lifr.lifr_nd.lnr_addr, &v6addr, sizeof (v6addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
	(void) memset(lifr.lifr_nd.lnr_hdw_addr, 0x55,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
	    sizeof (lifr.lifr_nd.lnr_hdw_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
	lifr.lifr_nd.lnr_hdw_len = 6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
	lifr.lifr_nd.lnr_state_create = ND_STALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
	lifr.lifr_nd.lnr_state_same_lla = ND_UNCHANGED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2657
	lifr.lifr_nd.lnr_state_diff_lla = ND_STALE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2658
	lifr.lifr_nd.lnr_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2659
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2660
	if (ioctl(s, SIOCLIFSETND, (caddr_t)&lifr) < 0)  {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2661
		Perror0_exit("SIOCLIFSETND");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2662
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2663
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2664
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2665
#endif /* DEBUG */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2667
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2668
 * Set tunnel source address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2669
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2670
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2671
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2672
setiftsrc(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2673
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2674
	return (settaddr(addr, icfg_set_tunnel_src));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2675
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2676
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2677
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2678
 * Set tunnel destination address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2679
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2680
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2681
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2682
setiftdst(char *addr, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2683
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2684
	return (settaddr(addr, icfg_set_tunnel_dest));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2685
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2686
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2687
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2688
 * sets tunnels src|dst address.  settaddr() expects the following:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2689
 * addr: Points to a printable string containing the address to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2690
 *       set, e.g. 129.153.128.110.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2691
 * fn:   Pointer to a libinetcfg routine that will do the actual work.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2692
 *       The only valid functions are icfg_set_tunnel_src and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2693
 *       icfg_set_tunnel_dest.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2694
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2695
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2696
settaddr(char *addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2697
    int (*fn)(icfg_handle_t, const struct sockaddr *, socklen_t))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2698
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2699
	icfg_handle_t handle;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2700
	icfg_if_t interface;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2701
	struct sockaddr_storage laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2702
	int lower;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2703
	int rc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2705
	if (strchr(name, ':') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2706
		errno = EPERM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2707
		Perror0_exit("Tunnel params on logical interfaces");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2708
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2709
	(void) strncpy(interface.if_name, name, sizeof (interface.if_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2710
	interface.if_protocol = SOCKET_AF(af);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2711
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2712
	/* Open interface. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2713
	if ((rc = icfg_open(&handle, &interface)) != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2714
		Perror0_exit((char *)icfg_errmsg(rc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2715
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2716
	rc = icfg_get_tunnel_lower(handle, &lower);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2717
	if (rc != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2718
		Perror0_exit((char *)icfg_errmsg(rc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2719
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2720
	if (lower == AF_INET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2721
		in_getaddr(addr, (struct sockaddr *)&laddr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2722
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2723
		in6_getaddr(addr, (struct sockaddr *)&laddr, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2724
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2725
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2726
	/* Call fn to do the real work, and close the interface. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2727
	rc = (*fn)(handle, (struct sockaddr *)&laddr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2728
	    sizeof (struct sockaddr_storage));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2729
	icfg_close(handle);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2730
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2731
	if (rc != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2732
		Perror0_exit((char *)icfg_errmsg(rc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2734
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2735
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2736
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2737
/* Set tunnel encapsulation limit. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2738
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2739
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2740
set_tun_encap_limit(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2741
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2742
	short limit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2743
	icfg_if_t interface;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2744
	icfg_handle_t handle;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2745
	int rc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2746
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2747
	if (strchr(name, ':') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2748
		errno = EPERM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2749
		Perror0_exit("Tunnel params on logical interfaces");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2750
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2751
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2752
	if ((sscanf(arg, "%hd", &limit) != 1) || (limit < 0) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2753
	    (limit > 255)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2754
		errno = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2755
		Perror0_exit("Invalid encapsulation limit");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2756
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2757
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2758
	/* Open interface for configuration. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2759
	(void) strncpy(interface.if_name, name, sizeof (interface.if_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2760
	interface.if_protocol = SOCKET_AF(af);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2761
	if (icfg_open(&handle, &interface) != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2762
		Perror0_exit("couldn't open interface");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2763
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2764
	rc = icfg_set_tunnel_encaplimit(handle, (int)limit);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2765
	icfg_close(handle);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2766
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2767
	if (rc != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2768
		Perror0_exit("Could not configure tunnel encapsulation limit");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2770
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2771
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2772
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2773
/* Disable encapsulation limit. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2774
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2775
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2776
clr_tun_encap_limit(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2777
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2778
	icfg_if_t interface;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2779
	icfg_handle_t handle;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2780
	int rc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2781
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2782
	if (strchr(name, ':') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2783
		errno = EPERM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2784
		Perror0_exit("Tunnel params on logical interfaces");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2785
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2786
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2787
	/* Open interface for configuration. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2788
	(void) strncpy(interface.if_name, name, sizeof (interface.if_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2789
	interface.if_protocol = SOCKET_AF(af);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2790
	if (icfg_open(&handle, &interface) != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2791
		Perror0_exit("couldn't open interface");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2792
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2793
	rc = icfg_set_tunnel_encaplimit(handle, -1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2794
	icfg_close(handle);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2795
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2796
	if (rc != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2797
		Perror0_exit((char *)icfg_errmsg(rc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2798
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2799
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2800
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2801
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2802
/* Set tunnel hop limit. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2803
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2804
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2805
set_tun_hop_limit(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2806
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2807
	unsigned short limit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2808
	icfg_if_t interface;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2809
	icfg_handle_t handle;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2810
	int rc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2811
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2812
	if (strchr(name, ':') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2813
		errno = EPERM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2814
		Perror0_exit("Tunnel params on logical interfaces");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2815
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2816
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2817
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2818
	 * Check limit here since it's really only an 8-bit unsigned quantity.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2819
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2820
	if ((sscanf(arg, "%hu", &limit) != 1) || (limit > 255)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2821
		errno = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2822
		Perror0_exit("Invalid hop limit");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2823
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2825
	/* Open interface for configuration. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2826
	(void) strncpy(interface.if_name, name, sizeof (interface.if_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2827
	interface.if_protocol = SOCKET_AF(af);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2828
	if (icfg_open(&handle, &interface) != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2829
		Perror0_exit("couldn't open interface");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2831
	rc = icfg_set_tunnel_hoplimit(handle, (uint8_t)limit);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2832
	icfg_close(handle);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2833
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2834
	if (rc != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2835
		Perror0_exit("Could not configure tunnel hop limit");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2836
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2837
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2838
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2839
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2840
/* Set zone ID */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2841
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2842
setzone(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2843
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2844
	zoneid_t zoneid = GLOBAL_ZONEID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2845
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2846
	if (param == NEXTARG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2847
		/* zone must be active */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2848
		if ((zoneid = getzoneidbyname(arg)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2849
			(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2850
			    "ifconfig: unknown zone '%s'\n", arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2851
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2852
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2853
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2854
	(void) strlcpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2855
	lifr.lifr_zoneid = zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2856
	if (ioctl(s, SIOCSLIFZONE, (caddr_t)&lifr) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2857
		Perror0_exit("SIOCSLIFZONE");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2858
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2859
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2860
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2861
/* Set source address to use */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2862
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2863
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2864
setifsrc(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2865
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2866
	uint_t ifindex = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2867
	int rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2868
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2869
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2870
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2871
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2872
	 * Argument can be either an interface name or "none". The latter means
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2873
	 * that any previous selection is cleared.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2874
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2875
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2876
	rval = strcmp(arg, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2877
	if (rval == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2878
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2879
		    "ifconfig: Cannot specify same interface for usesrc"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2880
		    " group\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2881
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2882
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2883
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2884
	rval = strcmp(arg, NONE_STR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2885
	if (rval != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2886
		if ((ifindex = if_nametoindex(arg)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2887
			(void) strncpy(lifr.lifr_name, arg, LIFNAMSIZ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2888
			Perror0_exit("Could not get interface index");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2889
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2890
		lifr.lifr_index = ifindex;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2891
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2892
		if (ioctl(s, SIOCGLIFUSESRC, (caddr_t)&lifr) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2893
			Perror0_exit("Not a valid usesrc consumer");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2894
		lifr.lifr_index = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2895
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2896
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2897
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2898
		(void) printf("setifsrc: lifr_name %s, lifr_index %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2899
		    lifr.lifr_name, lifr.lifr_index);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2900
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2901
	if (ioctl(s, SIOCSLIFUSESRC, (caddr_t)&lifr) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2902
		if (rval == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2903
			Perror0_exit("Cannot reset usesrc group");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2904
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2905
			Perror0_exit("Could not set source interface");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2906
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2907
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2908
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2909
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2910
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2911
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2912
 * Print the interface status line associated with `ifname'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2913
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2914
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2915
ifstatus(const char *ifname)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2916
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2917
	uint64_t flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2918
	char if_usesrc_name[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2919
	char *newbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2920
	int n, numifs, rval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2921
	struct lifreq *lifrp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2922
	struct lifsrcof lifs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2923
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2924
	(void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2925
	if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2926
		Perror0_exit("status: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2927
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2928
	flags = lifr.lifr_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2929
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2930
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2931
	 * In V4 compatibility mode, we don't print the IFF_IPV4 flag or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2932
	 * interfaces with IFF_IPV6 set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2933
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2934
	if (v4compat) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2935
		flags &= ~IFF_IPV4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2936
		if (flags & IFF_IPV6)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2937
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2938
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2939
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2940
	(void) printf("%s: ", ifname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2941
	print_flags(flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2942
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2943
	(void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2944
	if (ioctl(s, SIOCGLIFMETRIC, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2945
		Perror0_exit("status: SIOCGLIFMETRIC");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2946
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2947
		if (lifr.lifr_metric)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2948
			(void) printf(" metric %d", lifr.lifr_metric);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2949
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2950
	if (ioctl(s, SIOCGLIFMTU, (caddr_t)&lifr) >= 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2951
		(void) printf(" mtu %d", lifr.lifr_metric);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2952
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2953
	/* don't print index or zone when in compatibility mode */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2954
	if (!v4compat) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2955
		if (ioctl(s, SIOCGLIFINDEX, (caddr_t)&lifr) >= 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2956
			(void) printf(" index %d", lifr.lifr_index);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2957
		if (ioctl(s, SIOCGLIFZONE, (caddr_t)&lifr) >= 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2958
		    lifr.lifr_zoneid != getzoneid()) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2959
			char zone_name[ZONENAME_MAX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2960
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2961
			if (getzonenamebyid(lifr.lifr_zoneid, zone_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2962
			    sizeof (zone_name)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2963
				(void) printf("\n\tzone %d", lifr.lifr_zoneid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2964
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2965
				(void) printf("\n\tzone %s", zone_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2966
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2967
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2968
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2969
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2970
	if (ioctl(s, SIOCGLIFINDEX, (caddr_t)&lifr) >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2971
		lifs.lifs_ifindex = lifr.lifr_index;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2972
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2973
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2974
		 * Find the number of interfaces that use this interfaces'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2975
		 * address as a source address
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2976
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2977
		lifs.lifs_buf = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2978
		lifs.lifs_maxlen = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2979
		for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2980
			/* The first pass will give the bufsize we need */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2981
			rval = ioctl(s, SIOCGLIFSRCOF, (char *)&lifs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2982
			if (rval < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2983
				if (lifs.lifs_buf != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2984
					free(lifs.lifs_buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2985
					lifs.lifs_buf = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2986
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2987
				lifs.lifs_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2988
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2989
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2990
			if (lifs.lifs_len <= lifs.lifs_maxlen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2991
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2992
			/* Use kernel's size + a small margin to avoid loops */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2993
			lifs.lifs_maxlen = lifs.lifs_len +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2994
			    5 * sizeof (struct lifreq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2995
			/* For the first pass, realloc acts like malloc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2996
			newbuf = realloc(lifs.lifs_buf, lifs.lifs_maxlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2997
			if (newbuf == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2998
				if (lifs.lifs_buf != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2999
					free(lifs.lifs_buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3000
					lifs.lifs_buf = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3001
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3002
				lifs.lifs_len = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3003
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3004
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3005
			lifs.lifs_buf = newbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3006
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3007
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3008
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3009
		numifs = lifs.lifs_len / sizeof (struct lifreq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3010
		if (numifs > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3011
			lifrp = lifs.lifs_req;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3012
			(void) printf("\n\tsrcof");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3013
			for (n = numifs; n > 0; n--, lifrp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3014
				(void) printf(" %s", lifrp->lifr_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3015
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3016
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3017
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3018
		if (lifs.lifs_buf != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3019
			free(lifs.lifs_buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3020
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3021
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3022
	/* Find the interface whose source address this interface uses */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3023
	if (ioctl(s, SIOCGLIFUSESRC, (caddr_t)&lifr) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3024
		if (lifr.lifr_index != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3025
			if (if_indextoname(lifr.lifr_index,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3026
			    if_usesrc_name) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3027
				(void) printf("\n\tusesrc ifIndex %d",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3028
				    lifr.lifr_index);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3029
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3030
				(void) printf("\n\tusesrc %s", if_usesrc_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3031
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3032
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3033
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3034
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3035
	(void) putchar('\n');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3036
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3037
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3039
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3040
 * Print the status of the interface.  If an address family was
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3041
 * specified, show it and it only; otherwise, show them all.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3042
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3043
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3044
status(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3045
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3046
	struct afswtch *p = afp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3047
	uint64_t flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3048
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3049
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3050
	if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3051
		Perror0_exit("status: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3052
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3053
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3054
	flags = lifr.lifr_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3055
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3056
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3057
	 * Only print the interface status if the address family matches
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3058
	 * the interface family flag.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3059
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3060
	if (p != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3061
		if (((p->af_af == AF_INET6) && (flags & IFF_IPV4)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3062
		    ((p->af_af == AF_INET) && (flags & IFF_IPV6)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3063
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3064
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3065
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3066
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3067
	 * In V4 compatibility mode, don't print IFF_IPV6 interfaces.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3068
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3069
	if (v4compat && (flags & IFF_IPV6))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3070
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3071
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3072
	ifstatus(name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3073
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3074
	if (p != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3075
		(*p->af_status)(1, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3076
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3077
		for (p = afs; p->af_name; p++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3078
			(void) close(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3079
			s = socket(SOCKET_AF(p->af_af), SOCK_DGRAM, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3080
			/* set global af for use in p->af_status */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3081
			af = p->af_af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3082
			if (s == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3083
				Perror0_exit("socket");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3084
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3085
			(*p->af_status)(0, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3086
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3087
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3088
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3089
		 * Historically, 'ether' has been an address family,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3090
		 * so print it here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3091
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3092
		print_ifether(name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3093
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3094
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3095
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3096
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3097
 * Print the status of the interface in a format that can be used to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3098
 * reconfigure the interface later. Code stolen from status() above.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3099
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3100
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3101
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3102
configinfo(char *null, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3103
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3104
	struct afswtch *p = afp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3105
	uint64_t flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3106
	char phydevname[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3107
	char if_usesrc_name[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3108
	char *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3110
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3111
	if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3112
		Perror0_exit("status: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3113
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3114
	flags = lifr.lifr_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3116
	if (debug) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3117
		(void) printf("configinfo: name %s flags  0x%llx af_af %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3118
		    name, flags, p != NULL ? p->af_af : -1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3119
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3121
	/* remove LIF component */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3122
	(void) strncpy(phydevname, name, sizeof (phydevname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3123
	cp = strchr(phydevname, ':');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3124
	if (cp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3125
		*cp = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3126
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3127
	phydevname[sizeof (phydevname) - 1] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3128
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3129
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3130
	 * if the interface is IPv4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3131
	 *	if we have a IPv6 address family restriction return
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3132
	 *		so it won't print
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3133
	 *	if we are in IPv4 compatibility mode, clear out IFF_IPV4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3134
	 *		so we don't print it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3135
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3136
	if (flags & IFF_IPV4) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3137
		if (p && p->af_af == AF_INET6)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3138
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3139
		if (v4compat)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3140
			flags &= ~IFF_IPV4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3142
		(void) printf("%s inet plumb", phydevname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3143
	} else if (flags & IFF_IPV6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3144
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3145
		 * else if the interface is IPv6
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3146
		 *	if we have a IPv4 address family restriction return
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3147
		 *	or we are in IPv4 compatibiltiy mode, return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3148
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3149
		if (p && p->af_af == AF_INET)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3150
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3151
		if (v4compat)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3152
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3153
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3154
		(void) printf("%s inet6 plumb", phydevname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3155
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3156
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3157
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3158
	if (ioctl(s, SIOCGLIFMETRIC, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3159
		Perror0_exit("configinfo: SIOCGLIFMETRIC");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3160
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3161
		if (lifr.lifr_metric)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3162
			(void) printf(" metric %d ", lifr.lifr_metric);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3163
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3164
	if (((flags & (IFF_VIRTUAL|IFF_LOOPBACK)) != IFF_VIRTUAL) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3165
		ioctl(s, SIOCGLIFMTU, (caddr_t)&lifr) >= 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3166
		(void) printf(" mtu %d", lifr.lifr_metric);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3167
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3168
	/* don't print index when in compatibility mode */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3169
	if (!v4compat) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3170
		if (ioctl(s, SIOCGLIFINDEX, (caddr_t)&lifr) >= 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3171
			(void) printf(" index %d", lifr.lifr_index);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3172
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3174
	if (ioctl(s, SIOCGLIFUSESRC, (caddr_t)&lifr) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3175
		if (lifr.lifr_index != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3176
			if (if_indextoname(lifr.lifr_index,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3177
			    if_usesrc_name) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3178
				(void) printf(" usesrc %s", if_usesrc_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3179
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3180
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3181
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3183
	if (p != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3184
		(*p->af_configinfo)(1, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3185
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3186
		for (p = afs; p->af_name; p++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3187
			(void) close(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3188
			s = socket(SOCKET_AF(p->af_af), SOCK_DGRAM, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3189
			/* set global af for use in p->af_configinfo */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3190
			af = p->af_af;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3191
			if (s == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3192
				Perror0_exit("socket");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3193
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3194
			(*p->af_configinfo)(0, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3195
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3196
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3198
	(void) printf("\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3199
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3200
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3201
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3202
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3203
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3204
print_tsec(struct iftun_req *tparams)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3205
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3206
	ipsec_req_t *ipsr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3208
	(void) printf("\ttunnel security settings  ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3209
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3210
	 * Deal with versioning, for now just point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3211
	 * an ipsec_req_t at ifta_secinfo.  If versions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3212
	 * change, something else will overlay ifta_secinfo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3213
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3214
	assert(tparams->ifta_vers == IFTUN_VERSION);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3216
	ipsr = (ipsec_req_t *)(&tparams->ifta_secinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3217
	if (ipsr->ipsr_ah_req & IPSEC_PREF_REQUIRED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3218
		(void) printf("ah (%s)  ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3219
		    rparsealg(ipsr->ipsr_auth_alg, IPSEC_PROTO_AH));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3220
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3221
	if (ipsr->ipsr_esp_req & IPSEC_PREF_REQUIRED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3222
		(void) printf("esp (%s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3223
		    rparsealg(ipsr->ipsr_esp_alg, IPSEC_PROTO_ESP));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3224
		(void) printf("/%s)",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3225
		    rparsealg(ipsr->ipsr_esp_auth_alg, IPSEC_PROTO_AH));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3226
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3227
	(void) printf("\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3228
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3229
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3230
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3231
tun_status(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3232
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3233
	icfg_if_t interface;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3234
	int rc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3235
	icfg_handle_t handle;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3236
	int protocol;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3237
	char srcbuf[INET6_ADDRSTRLEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3238
	char dstbuf[INET6_ADDRSTRLEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3239
	boolean_t tabbed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3240
	uint8_t hoplimit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3241
	int16_t encaplimit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3242
	struct sockaddr_storage taddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3243
	socklen_t socklen = sizeof (taddr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3245
	(void) strncpy(interface.if_name, name, sizeof (interface.if_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3246
	interface.if_protocol = SOCKET_AF(af);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3247
	if ((rc = icfg_open(&handle, &interface)) != ICFG_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3248
		Perror0_exit((char *)icfg_errmsg(rc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3250
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3251
	 * only print tunnel info for lun 0.  If ioctl fails, assume
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3252
	 * we are not a tunnel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3253
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3254
	if (strchr(name, ':') != NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3255
	    icfg_get_tunnel_lower(handle, &protocol) != ICFG_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3256
		icfg_close(handle);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3257
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3258
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3259
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3260
	switch (protocol) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3261
	case AF_INET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3262
		(void) printf("\tinet");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3263
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3264
	case AF_INET6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3265
		(void) printf("\tinet6");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3266
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3267
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3268
		Perror0_exit("\ttunnel: Illegal lower stream\n\t");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3269
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3270
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3271
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3272
	rc = icfg_get_tunnel_src(handle, (struct sockaddr *)&taddr, &socklen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3273
	if (rc == ICFG_NOT_SET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3274
		(void) strlcpy(srcbuf, (protocol == AF_INET) ? "0.0.0.0" :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3275
		    "::", sizeof (srcbuf));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3276
	} else if (rc != ICFG_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3277
		Perror0_exit((char *)icfg_errmsg(rc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3278
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3279
		rc = icfg_sockaddr_to_str(protocol, (struct sockaddr *)&taddr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3280
		    srcbuf, sizeof (srcbuf));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3281
		if (rc != ICFG_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3282
			Perror0_exit((char *)icfg_errmsg(rc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3283
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3284
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3285
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3286
	(void) printf(" tunnel src %s ", srcbuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3288
	rc = icfg_get_tunnel_dest(handle, (struct sockaddr *)&taddr, &socklen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3289
	if (rc == ICFG_NOT_SET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3290
		(void) printf("\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3291
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3292
		rc = icfg_sockaddr_to_str(protocol, (struct sockaddr *)&taddr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3293
		    dstbuf, sizeof (dstbuf));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3294
		if (rc != ICFG_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3295
			Perror0_exit((char *)icfg_errmsg(rc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3296
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3297
		(void) printf("tunnel dst %s\n", dstbuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3298
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3299
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3300
	if (handle->ifh_tunnel_params != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3301
	    (handle->ifh_tunnel_params->ifta_flags & IFTUN_SECURITY))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3302
		print_tsec(handle->ifh_tunnel_params);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3304
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3305
	 * tabbed indicates tabbed and printed.  Use it tell us whether
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3306
	 * to tab and that we've printed something here, so we need a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3307
	 * newline
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3308
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3309
	tabbed = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3311
	if (icfg_get_tunnel_hoplimit(handle, &hoplimit) == ICFG_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3312
		(void) printf("\ttunnel hop limit %d ", hoplimit);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3313
		tabbed = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3314
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3316
	if ((protocol == AF_INET6) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3317
	    (icfg_get_tunnel_encaplimit(handle, &encaplimit) ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3318
		ICFG_SUCCESS)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3319
		if (!tabbed) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3320
			(void) printf("\t");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3321
			tabbed = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3322
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3323
		if (encaplimit >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3324
			(void) printf("tunnel encapsulation limit %d",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3325
			    encaplimit);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3326
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3327
			(void) printf("tunnel encapsulation limit disabled");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3328
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3329
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3330
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3331
	if (tabbed)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3332
		(void) printf("\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3334
	icfg_close(handle);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3335
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3337
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3338
in_status(int force, uint64_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3339
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3340
	struct sockaddr_in *sin, *laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3341
	struct	sockaddr_in netmask = { AF_INET };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3343
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3344
		(void) printf("in_status(%s) flags 0x%llx\n", name, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3346
	/* only print status for IPv4 interfaces */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3347
	if (!(flags & IFF_IPV4))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3348
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3350
	/* if the interface is a tunnel, print the tunnel status */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3351
	tun_status();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3352
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3353
	if (!(flags & IFF_NOLOCAL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3354
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3355
		if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3356
			if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3357
			    errno == ENXIO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3358
				if (!force)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3359
					return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3360
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3361
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3362
			} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3363
				Perror0_exit("in_status: SIOCGLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3364
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3365
		sin = (struct sockaddr_in *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3366
		(void) printf("\tinet %s ", inet_ntoa(sin->sin_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3367
		laddr = sin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3368
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3369
		(void) printf("\tinet ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3370
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3372
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3373
	if (ioctl(s, SIOCGLIFSUBNET, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3374
		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3375
		    errno == ENXIO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3376
			if (!force)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3377
				return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3378
			(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3379
			    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3380
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3381
			Perror0_exit("in_status: SIOCGLIFSUBNET");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3382
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3383
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3384
	sin = (struct sockaddr_in *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3385
	if ((flags & IFF_NOLOCAL) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3386
	    sin->sin_addr.s_addr != laddr->sin_addr.s_addr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3387
		(void) printf("subnet %s/%d ", inet_ntoa(sin->sin_addr),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3388
		    lifr.lifr_addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3389
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3390
	if (sin->sin_family != AF_INET) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3391
		(void) printf("Wrong family: %d\n", sin->sin_family);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3392
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3394
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3395
	if (ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3396
		if (errno != EADDRNOTAVAIL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3397
			Perror0_exit("in_status: SIOCGLIFNETMASK");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3398
		(void) memset(&lifr.lifr_addr, 0, sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3399
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3400
		netmask.sin_addr =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3401
		    ((struct sockaddr_in *)&lifr.lifr_addr)->sin_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3402
	if (flags & IFF_POINTOPOINT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3403
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3404
		if (ioctl(s, SIOCGLIFDSTADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3405
			if (errno == EADDRNOTAVAIL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3406
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3407
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3408
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3409
			    Perror0_exit("in_status: SIOCGLIFDSTADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3410
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3411
		sin = (struct sockaddr_in *)&lifr.lifr_dstaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3412
		(void) printf("--> %s ", inet_ntoa(sin->sin_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3413
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3414
	(void) printf("netmask %x ", ntohl(netmask.sin_addr.s_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3415
	if (flags & IFF_BROADCAST) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3416
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3417
		if (ioctl(s, SIOCGLIFBRDADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3418
			if (errno == EADDRNOTAVAIL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3419
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3420
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3421
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3422
			    Perror0_exit("in_status: SIOCGLIFBRDADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3423
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3424
		sin = (struct sockaddr_in *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3425
		if (sin->sin_addr.s_addr != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3426
			(void) printf("broadcast %s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3427
			    inet_ntoa(sin->sin_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3428
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3429
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3430
	/* If there is a groupname, print it for lun 0 alone */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3431
	if (strchr(name, ':') == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3432
		(void) memset(lifr.lifr_groupname, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3433
		    sizeof (lifr.lifr_groupname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3434
		if (ioctl(s, SIOCGLIFGROUPNAME, (caddr_t)&lifr) >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3435
			if (strlen(lifr.lifr_groupname) > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3436
				(void) printf("\n\tgroupname %s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3437
				    lifr.lifr_groupname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3438
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3439
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3440
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3441
	(void) putchar('\n');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3442
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3444
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3445
in6_status(int force, uint64_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3446
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3447
	char abuf[INET6_ADDRSTRLEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3448
	struct sockaddr_in6 *sin6, *laddr6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3449
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3450
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3451
		(void) printf("in6_status(%s) flags 0x%llx\n", name, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3453
	if (!(flags & IFF_IPV6))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3454
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3455
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3456
	/* if the interface is a tunnel, print the tunnel status */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3457
	tun_status();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3458
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3459
	if (!(flags & IFF_NOLOCAL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3460
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3461
		if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3462
			if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3463
			    errno == ENXIO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3464
				if (!force)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3465
					return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3466
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3467
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3468
			} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3469
				Perror0_exit("in_status6: SIOCGLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3470
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3471
		sin6 = (struct sockaddr_in6 *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3472
		(void) printf("\tinet6 %s/%d ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3473
		    inet_ntop(AF_INET6, (void *)&sin6->sin6_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3474
		    abuf, sizeof (abuf)),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3475
		    lifr.lifr_addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3476
		laddr6 = sin6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3477
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3478
		(void) printf("\tinet6 ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3479
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3480
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3481
	if (ioctl(s, SIOCGLIFSUBNET, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3482
		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3483
		    errno == ENXIO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3484
			if (!force)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3485
				return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3486
			(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3487
			    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3488
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3489
			Perror0_exit("in_status6: SIOCGLIFSUBNET");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3490
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3491
	sin6 = (struct sockaddr_in6 *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3492
	if ((flags & IFF_NOLOCAL) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3493
	    !IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &laddr6->sin6_addr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3494
		(void) printf("subnet %s/%d ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3495
		    inet_ntop(AF_INET6, (void *)&sin6->sin6_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3496
		    abuf, sizeof (abuf)),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3497
		    lifr.lifr_addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3498
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3499
	if (sin6->sin6_family != AF_INET6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3500
		(void) printf("Wrong family: %d\n", sin6->sin6_family);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3501
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3502
	if (flags & IFF_POINTOPOINT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3503
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3504
		if (ioctl(s, SIOCGLIFDSTADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3505
			if (errno == EADDRNOTAVAIL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3506
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3507
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3508
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3509
			    Perror0_exit("in_status6: SIOCGLIFDSTADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3510
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3511
		sin6 = (struct sockaddr_in6 *)&lifr.lifr_dstaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3512
		(void) printf("--> %s ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3513
		    inet_ntop(AF_INET6, (void *)&sin6->sin6_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3514
		    abuf, sizeof (abuf)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3515
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3516
	if (verbose) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3517
		(void) putchar('\n');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3518
		(void) putchar('\t');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3519
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3520
		if (ioctl(s, SIOCGLIFTOKEN, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3521
			if (errno == EADDRNOTAVAIL || errno == EINVAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3522
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3523
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3524
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3525
			    Perror0_exit("in_status6: SIOCGLIFTOKEN");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3526
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3527
			sin6 = (struct sockaddr_in6 *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3528
			(void) printf("token %s/%d ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3529
			    inet_ntop(AF_INET6, (void *)&sin6->sin6_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3530
			    abuf, sizeof (abuf)),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3531
			    lifr.lifr_addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3532
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3533
		if (ioctl(s, SIOCGLIFLNKINFO, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3534
			if (errno != EINVAL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3535
				Perror0_exit("in_status6: SIOCGLIFLNKINFO");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3536
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3537
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3538
			(void) printf("maxhops %u, reachtime %u ms, "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3539
			    "reachretrans %u ms, maxmtu %u ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3540
			    lifr.lifr_ifinfo.lir_maxhops,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3541
			    lifr.lifr_ifinfo.lir_reachtime,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3542
			    lifr.lifr_ifinfo.lir_reachretrans,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3543
			    lifr.lifr_ifinfo.lir_maxmtu);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3544
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3545
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3546
	/* If there is a groupname, print it for lun 0 alone */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3547
	if (strchr(name, ':') == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3548
		(void) memset(lifr.lifr_groupname, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3549
		    sizeof (lifr.lifr_groupname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3550
		if (ioctl(s, SIOCGLIFGROUPNAME, (caddr_t)&lifr) >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3551
			if (strlen(lifr.lifr_groupname) > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3552
				(void) printf("\n\tgroupname %s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3553
				    lifr.lifr_groupname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3554
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3555
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3556
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3557
	(void) putchar('\n');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3558
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3559
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3560
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3561
in_configinfo(int force, uint64_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3562
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3563
	struct sockaddr_in *sin, *laddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3564
	struct	sockaddr_in netmask = { AF_INET };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3565
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3566
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3567
		(void) printf("in_configinfo(%s) flags 0x%llx\n", name, flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3568
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3569
	/* only configinfo info for IPv4 interfaces */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3570
	if (!(flags & IFF_IPV4))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3571
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3572
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3573
	if (!(flags & IFF_NOLOCAL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3574
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3575
		if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3576
			if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3577
			    errno == ENXIO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3578
				if (!force)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3579
					return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3580
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3581
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3582
			} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3583
				Perror0_exit("in_configinfo: SIOCGLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3584
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3585
		sin = (struct sockaddr_in *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3586
		if (get_lun(name) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3587
			(void) printf(" addif %s ", inet_ntoa(sin->sin_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3588
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3589
			(void) printf(" set %s ", inet_ntoa(sin->sin_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3590
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3591
		laddr = sin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3592
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3593
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3594
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3595
	if (ioctl(s, SIOCGLIFSUBNET, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3596
		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3597
		    errno == ENXIO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3598
			if (!force)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3599
				return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3600
			(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3601
			    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3602
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3603
			Perror0_exit("in_configinfo: SIOCGLIFSUBNET");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3604
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3605
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3606
	sin = (struct sockaddr_in *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3608
	if ((flags & IFF_NOLOCAL) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3609
	    sin->sin_addr.s_addr != laddr->sin_addr.s_addr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3610
		(void) printf(" subnet %s/%d ", inet_ntoa(sin->sin_addr),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3611
		    lifr.lifr_addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3612
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3613
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3614
	if (ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3615
		if (errno != EADDRNOTAVAIL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3616
			Perror0_exit("in_configinfo: SIOCGLIFNETMASK");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3617
		(void) memset(&lifr.lifr_addr, 0, sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3618
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3619
		netmask.sin_addr =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3620
		    ((struct sockaddr_in *)&lifr.lifr_addr)->sin_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3621
	if (flags & IFF_POINTOPOINT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3622
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3623
		if (ioctl(s, SIOCGLIFDSTADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3624
			if (errno == EADDRNOTAVAIL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3625
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3626
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3627
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3628
			    Perror0_exit("in_configinfo: SIOCGLIFDSTADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3629
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3630
		sin = (struct sockaddr_in *)&lifr.lifr_dstaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3631
		(void) printf(" destination %s ", inet_ntoa(sin->sin_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3632
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3633
	(void) printf(" netmask 0x%x ", ntohl(netmask.sin_addr.s_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3634
	if (flags & IFF_BROADCAST) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3635
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3636
		if (ioctl(s, SIOCGLIFBRDADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3637
			if (errno == EADDRNOTAVAIL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3638
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3639
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3640
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3641
			    Perror0_exit("in_configinfo: SIOCGLIFBRDADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3642
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3643
		sin = (struct sockaddr_in *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3644
		if (sin->sin_addr.s_addr != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3645
			(void) printf(" broadcast %s ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3646
			    inet_ntoa(sin->sin_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3647
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3648
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3650
	/* If there is a groupname, print it for lun 0 alone */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3651
	if (get_lun(name) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3652
		(void) memset(lifr.lifr_groupname, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3653
		    sizeof (lifr.lifr_groupname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3654
		if (ioctl(s, SIOCGLIFGROUPNAME, (caddr_t)&lifr) >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3655
			if (strlen(lifr.lifr_groupname) > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3656
				(void) printf(" group %s ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3657
				    lifr.lifr_groupname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3658
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3659
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3660
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3661
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3662
	/* Print flags to configure */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3663
	print_config_flags(flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3664
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3665
	/* IFF_NOARP applies to AF_INET only */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3666
	if (flags & IFF_NOARP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3667
		(void) printf("-arp ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3668
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3669
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3670
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3671
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3672
in6_configinfo(int force, uint64_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3673
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3674
	char abuf[INET6_ADDRSTRLEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3675
	struct sockaddr_in6 *sin6, *laddr6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3676
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3677
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3678
		(void) printf("in6_configinfo(%s) flags 0x%llx\n", name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3679
		    flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3680
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3681
	if (!(flags & IFF_IPV6))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3682
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3683
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3684
	if (!(flags & IFF_NOLOCAL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3685
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3686
		if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3687
			if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3688
			    errno == ENXIO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3689
				if (!force)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3690
					return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3691
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3692
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3693
			} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3694
				Perror0_exit("in6_configinfo: SIOCGLIFADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3695
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3696
		sin6 = (struct sockaddr_in6 *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3697
		if (get_lun(name) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3698
			(void) printf(" addif %s/%d ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3699
			    inet_ntop(AF_INET6, (void *)&sin6->sin6_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3700
			    abuf, sizeof (abuf)),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3701
			    lifr.lifr_addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3702
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3703
			(void) printf(" set %s/%d ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3704
			    inet_ntop(AF_INET6, (void *)&sin6->sin6_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3705
			    abuf, sizeof (abuf)),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3706
			    lifr.lifr_addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3707
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3708
		laddr6 = sin6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3709
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3710
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3711
	if (ioctl(s, SIOCGLIFSUBNET, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3712
		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3713
		    errno == ENXIO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3714
			if (!force)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3715
				return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3716
			(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3717
			    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3718
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3719
			Perror0_exit("in6_configinfo: SIOCGLIFSUBNET");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3720
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3721
	sin6 = (struct sockaddr_in6 *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3722
	if ((flags & IFF_NOLOCAL) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3723
	    !IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &laddr6->sin6_addr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3724
		(void) printf(" subnet %s/%d ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3725
		    inet_ntop(AF_INET6, (void *)&sin6->sin6_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3726
		    abuf, sizeof (abuf)),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3727
		    lifr.lifr_addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3728
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3730
	if (flags & IFF_POINTOPOINT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3731
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3732
		if (ioctl(s, SIOCGLIFDSTADDR, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3733
			if (errno == EADDRNOTAVAIL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3734
				(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3735
				    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3736
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3737
			    Perror0_exit("in6_configinfo: SIOCGLIFDSTADDR");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3738
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3739
		sin6 = (struct sockaddr_in6 *)&lifr.lifr_dstaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3740
		(void) printf(" destination %s ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3741
		    inet_ntop(AF_INET6, (void *)&sin6->sin6_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3742
		    abuf, sizeof (abuf)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3743
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3744
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3745
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3746
	if (ioctl(s, SIOCGLIFTOKEN, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3747
		if (errno == EADDRNOTAVAIL || errno == EINVAL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3748
			(void) memset(&lifr.lifr_addr, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3749
			    sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3750
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3751
		    Perror0_exit("in6_configinfo: SIOCGLIFTOKEN");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3752
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3753
		sin6 = (struct sockaddr_in6 *)&lifr.lifr_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3754
		(void) printf(" token %s/%d ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3755
		    inet_ntop(AF_INET6, (void *)&sin6->sin6_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3756
		    abuf, sizeof (abuf)),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3757
		    lifr.lifr_addrlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3758
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3759
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3760
	/* If there is a groupname, print it for lun 0 alone */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3761
	if (get_lun(name) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3762
		(void) memset(lifr.lifr_groupname, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3763
		    sizeof (lifr.lifr_groupname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3764
		if (ioctl(s, SIOCGLIFGROUPNAME, (caddr_t)&lifr) >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3765
			if (strlen(lifr.lifr_groupname) > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3766
				(void) printf(" group %s ",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3767
				    lifr.lifr_groupname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3768
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3769
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3770
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3771
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3772
	/* Print flags to configure */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3773
	print_config_flags(flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3775
	/* IFF_NONUD applies to AF_INET6 only */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3776
	if (flags & IFF_NONUD) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3777
		(void) printf("-nud ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3778
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3779
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3780
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3781
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3782
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3783
get_lun(char *rsrc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3784
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3785
	char resource[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3786
	char *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3787
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3788
	(void) strcpy(resource, rsrc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3789
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3790
	/* remove LIF component */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3791
	cp = strchr(resource, ':');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3792
	if (cp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3793
		cp++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3794
		return (atoi(cp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3795
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3797
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3798
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3799
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3800
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3801
 * We need to plink both the arp-device stream and the arp-ip-device stream.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3802
 * However the muxid is stored only in IP. Plumbing 2 streams individually
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3803
 * is not atomic, and if ifconfig is killed, the resulting plumbing can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3804
 * be inconsistent. For eg. if only the arp stream is plumbed, we have lost
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3805
 * the muxid, and the half-baked plumbing can neither be unplumbed nor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3806
 * replumbed, thus requiring a reboot. To avoid the above the following
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3807
 * scheme is used.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3808
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3809
 * Ifconfig asks IP to enforce atomicity of plumbing the arp and IP streams.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3810
 * This is done by pushing arp on to the mux (/dev/udp). ARP adds some
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3811
 * extra information in the I_PLINK and I_PUNLINK ioctls to let IP know
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3812
 * that the plumbing/unplumbing has to be done atomically. Ifconfig plumbs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3813
 * the IP stream first, and unplumbs it last. The kernel (IP) does not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3814
 * allow IP stream to be unplumbed without unplumbing arp stream. Similarly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3815
 * it does not allow arp stream to be plumbed before IP stream is plumbed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3816
 * There is no need to use SIOCSLIFMUXID, since the whole operation is atomic,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3817
 * and IP uses the info in the I_PLINK message to get the muxid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3818
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3819
 * a. STREAMS does not allow us to use /dev/ip itself as the mux. So we use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3820
 *    /dev/udp[6].
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3821
 * b. SIOCGLIFMUXID returns the muxid corresponding to the V4 or V6 stream
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3822
 *    depending on the open i.e. V4 vs V6 open. So we need to use /dev/udp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3823
 *    or /dev/udp6.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3824
 * c. We need to push ARP in order to get the required kernel support for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3825
 *    atomic plumbings. The actual work done by ARP is explained in arp.c
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3826
 *    Without pushing ARP, we will still be able to plumb/unplumb. But
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3827
 *    it is not atomic, and is supported by the kernel for backward
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3828
 *    compatibility for other utilities like atmifconfig etc. In this case
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3829
 *    the utility must use SIOCSLIFMUXID.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3830
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3831
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3832
plumb_one_device(dlpi_if_attr_t *diap, int ip_fd, int af)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3833
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3834
	int	arp_fd = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3835
	int	arp_muxid = -1, ip_muxid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3836
	int	mux_fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3837
	char	*udp_dev_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3838
	dlpi_if_attr_t	dia;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3839
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3840
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3841
		(void) printf("plumb_one_device: ifname %s, ppa %d\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3842
		    diap->ifname, diap->ppa);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3843
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3844
	if (diap->style == DL_STYLE2 && dlpi_detach(ip_fd, -1) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3845
		Perror0_exit("dlpi_detach");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3846
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3847
	if (ioctl(ip_fd, I_PUSH, IP_MOD_NAME) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3848
		Perror2_exit("I_PUSH", IP_MOD_NAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3850
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3851
	 * Push the ARP module onto the interface stream. IP uses
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3852
	 * this to send resolution requests up to ARP. We need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3853
	 * do this before the SLIFNAME ioctl is sent down because
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3854
	 * the interface becomes publicly known as soon as the SLIFNAME
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3855
	 * ioctl completes. Thus some other process trying to bring up
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3856
	 * the interface after SLIFNAME but before we have pushed ARP
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3857
	 * could hang. We pop the module again later if it is not needed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3858
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3859
	if (ioctl(ip_fd, I_PUSH, ARP_MOD_NAME) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3860
		Perror2_exit("I_PUSH", ARP_MOD_NAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3861
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3862
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3863
	 * Set IFF_IPV4/IFF_IPV6 flags.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3864
	 * At this point in time the kernel also allows an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3865
	 * override of the CANTCHANGE flags.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3866
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3867
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3868
	lifr.lifr_name[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3869
	if (ioctl(ip_fd, SIOCGLIFFLAGS, (char *)&lifr) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3870
		Perror0_exit("plumb_one_device: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3871
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3872
	/* Set the name string and the IFF_IPV* flag */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3873
	if (af == AF_INET6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3874
		lifr.lifr_flags |= IFF_IPV6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3875
		lifr.lifr_flags &= ~(IFF_BROADCAST | IFF_IPV4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3876
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3877
		lifr.lifr_flags |= IFF_IPV4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3878
		lifr.lifr_flags &= ~IFF_IPV6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3879
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3880
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3881
	/* record the device and module names as interface name */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3882
	lifr.lifr_ppa = diap->ppa;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3883
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3884
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3885
	/* set the interface name */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3886
	if (ioctl(ip_fd, SIOCSLIFNAME, (char *)&lifr) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3887
		if (errno != EEXIST)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3888
			Perror0_exit("SIOCSLIFNAME for ip");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3889
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3890
		 * This difference between the way we behave for EEXIST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3891
		 * and that with other errors exists to preserve legacy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3892
		 * behaviour. Earlier when foreachinterface() and matcif()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3893
		 * were doing the duplicate interface name checks, for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3894
		 * already existing interfaces, inetplumb() returned "0".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3895
		 * To preserve this behaviour, Perror0() and return are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3896
		 * called for EEXIST.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3897
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3898
		Perror0("SIOCSLIFNAME for ip");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3899
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3900
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3901
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3902
	/* Get the full set of existing flags for this stream */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3903
	if (ioctl(ip_fd, SIOCGLIFFLAGS, (char *)&lifr) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3904
		Perror0_exit("plumb_one_device: SIOCFLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3905
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3906
	if (debug) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3907
		(void) printf("plumb_one_device: %s got flags: \n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3908
		    lifr.lifr_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3909
		print_flags(lifr.lifr_flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3910
		(void) putchar('\n');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3911
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3912
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3913
	/* Check if arp is not actually needed */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3914
	if (lifr.lifr_flags & (IFF_NOARP|IFF_IPV6)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3915
		if (ioctl(ip_fd, I_POP, 0) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3916
			Perror2_exit("I_POP", ARP_MOD_NAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3917
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3918
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3919
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3920
	 * Open "/dev/udp" for use as a multiplexor to PLINK the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3921
	 * interface stream under. We use "/dev/udp" instead of "/dev/ip"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3922
	 * since STREAMS will not let you PLINK a driver under itself,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3923
	 * and "/dev/ip" is typically the driver at the bottom of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3924
	 * the stream for tunneling interfaces.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3925
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3926
	if (af == AF_INET6)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3927
		udp_dev_name = UDP6_DEV_NAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3928
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3929
		udp_dev_name = UDP_DEV_NAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3930
	if ((mux_fd = open_arp_on_udp(udp_dev_name)) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3931
		exit(EXIT_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3932
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3933
	/* Check if arp is not needed */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3934
	if (lifr.lifr_flags & (IFF_NOARP|IFF_IPV6)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3935
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3936
		 * PLINK the interface stream so that ifconfig can exit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3937
		 * without tearing down the stream.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3938
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3939
		if ((ip_muxid = ioctl(mux_fd, I_PLINK, ip_fd)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3940
			Perror0_exit("I_PLINK for ip");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3941
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3942
		(void) close(mux_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3943
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3944
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3945
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3946
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3947
	 * This interface does use ARP, so set up a separate stream
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3948
	 * from the interface to ARP.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3949
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3950
	 * Note: modules specified by the user are pushed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3951
	 * only on the interface stream, not on the ARP stream.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3952
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3953
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3954
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3955
		(void) printf("plumb_one_device: ifname: %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3956
		    diap->ifname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3957
	arp_fd = dlpi_if_open(diap->ifname, &dia, _B_FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3958
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3959
	if (dia.style == DL_STYLE2 && dlpi_detach(arp_fd, -1) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3960
		Perror0_exit("dlpi_detach");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3961
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3962
	if (ioctl(arp_fd, I_PUSH, ARP_MOD_NAME) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3963
		Perror2_exit("I_PUSH", ARP_MOD_NAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3964
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3965
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3966
	 * Tell ARP the name and unit number for this interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3967
	 * Note that arp has no support for transparent ioctls.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3968
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3969
	if (strioctl(arp_fd, SIOCSLIFNAME, (char *)&lifr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3970
	    sizeof (lifr)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3971
		if (errno != EEXIST)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3972
			Perror0_exit("SIOCSLIFNAME for arp");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3973
		Perror0("SIOCSLIFNAME for arp");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3974
		(void) close(arp_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3975
		(void) close(mux_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3976
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3977
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3978
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3979
	 * PLINK the IP and ARP streams so that ifconfig can exit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3980
	 * without tearing down the stream.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3981
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3982
	if ((ip_muxid = ioctl(mux_fd, I_PLINK, ip_fd)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3983
		Perror0_exit("I_PLINK for ip");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3984
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3985
	if ((arp_muxid = ioctl(mux_fd, I_PLINK, arp_fd)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3986
		(void) ioctl(mux_fd, I_PUNLINK, ip_muxid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3987
		Perror0_exit("I_PLINK for arp");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3988
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3989
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3990
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3991
		(void) printf("arp muxid = %d\n", arp_muxid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3992
	(void) close(arp_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3993
	(void) close(mux_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3994
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3995
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3996
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3997
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3998
 * If this is a physical interface then remove it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3999
 * If it is a logical interface name use SIOCLIFREMOVEIF to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4000
 * remove it. In both cases fail if it doesn't exist.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4001
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4002
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4003
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4004
inetunplumb(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4005
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4006
	int ip_muxid, arp_muxid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4007
	int mux_fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4008
	char *udp_dev_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4009
	char *strptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4010
	uint64_t flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4011
	boolean_t changed_arp_muxid = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4012
	int save_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4013
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4014
	strptr = strchr(name, ':');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4015
	if (strptr != NULL || strcmp(name, LOOPBACK_IF) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4016
		/* Can't unplumb logical interface zero */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4017
		if (strptr != NULL && strcmp(strptr, ":0") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4018
			(void) fprintf(stderr, "ifconfig: unplumb:"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4019
			    " Cannot unplumb %s: Invalid interface\n", name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4020
			exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4021
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4022
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4023
		(void) memset(&lifr.lifr_addr, 0, sizeof (lifr.lifr_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4024
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4025
		if (ioctl(s, SIOCLIFREMOVEIF, (caddr_t)&lifr) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4026
			Perror0_exit("unplumb: SIOCLIFREMOVEIF");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4027
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4028
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4029
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4030
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4031
	 * We used /dev/udp or udp6 to set up the mux. So we have to use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4032
	 * the same now for PUNLINK also.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4033
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4034
	if (afp->af_af == AF_INET6)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4035
		udp_dev_name = UDP6_DEV_NAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4036
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4037
		udp_dev_name = UDP_DEV_NAME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4039
	if ((mux_fd = open_arp_on_udp(udp_dev_name)) == -1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4040
		exit(EXIT_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4041
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4042
	(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4043
	if (ioctl(mux_fd, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4044
		Perror0_exit("unplumb: SIOCGLIFFLAGS");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4045
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4046
	flags = lifr.lifr_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4047
	if (ioctl(mux_fd, SIOCGLIFMUXID, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4048
		Perror0_exit("unplumb: SIOCGLIFMUXID");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4049
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4050
	arp_muxid = lifr.lifr_arp_muxid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4051
	ip_muxid = lifr.lifr_ip_muxid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4052
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4053
	 * We don't have a good way of knowing whether the arp stream is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4054
	 * plumbed. We can't rely on IFF_NOARP because someone could
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4055
	 * have turned it off later using "ifconfig xxx -arp".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4056
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4057
	if (arp_muxid != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4058
		if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4059
			(void) printf("arp_muxid %d\n", arp_muxid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4060
		if (ioctl(mux_fd, I_PUNLINK, arp_muxid) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4061
			if ((errno == EINVAL) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4062
			    (flags & (IFF_NOARP | IFF_IPV6))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4063
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4064
				 * Some plumbing utilities set the muxid to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4065
				 * -1 or some invalid value to signify that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4066
				 * there is no arp stream. Set the muxid to 0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4067
				 * before trying to unplumb the IP stream.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4068
				 * IP does not allow the IP stream to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4069
				 * unplumbed if it sees a non-null arp muxid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4070
				 * for consistency of IP-ARP streams.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4071
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4072
				lifr.lifr_arp_muxid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4073
				(void) ioctl(mux_fd, SIOCSLIFMUXID,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4074
				    (caddr_t)&lifr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4075
				changed_arp_muxid = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4076
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4077
				Perror0("I_PUNLINK for arp");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4078
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4079
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4080
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4081
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4082
		(void) printf("ip_muxid %d\n", ip_muxid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4083
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4084
	if (ioctl(mux_fd, I_PUNLINK, ip_muxid) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4085
		if (changed_arp_muxid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4086
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4087
			 * Some error occurred, and we need to restore
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4088
			 * everything back to what it was.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4089
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4090
			save_errno = errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4091
			lifr.lifr_arp_muxid = arp_muxid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4092
			lifr.lifr_ip_muxid = ip_muxid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4093
			(void) ioctl(mux_fd, SIOCSLIFMUXID, (caddr_t)&lifr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4094
			errno = save_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4095
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4096
		Perror0_exit("I_PUNLINK for ip");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4097
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4098
	(void) close(mux_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4099
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4100
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4102
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4103
 * If this is a physical interface then create it unless it is already
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4104
 * present. If it is a logical interface name use SIOCLIFADDIF to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4105
 * create and (and fail it if already exists.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4106
 * As a special case send SIOCLIFADDIF for the loopback interface. This
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4107
 * is needed since there is no other notion of plumbing the loopback
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4108
 * interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4109
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4110
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4111
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4112
inetplumb(char *arg, int64_t param)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4113
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4114
	char		*strptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4115
	int		dev_fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4116
	dlpi_if_attr_t	dia;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4117
	boolean_t	islo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4119
	strptr = strchr(name, ':');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4120
	islo = (strcmp(name, LOOPBACK_IF) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4121
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4122
	if (strptr != NULL || islo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4123
		(void) memset(&lifr, 0, sizeof (lifr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4124
		(void) strlcpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4125
		if (islo && ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) >= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4126
			if (debug) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4127
				(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4128
				    "ifconfig: %s already exists\n", name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4129
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4130
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4131
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4132
		if (ioctl(s, SIOCLIFADDIF, (caddr_t)&lifr) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4133
			if (errno == EEXIST) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4134
				if (debug) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4135
					(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4136
					    "ifconfig: %s already exists\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4137
					    name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4138
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4139
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4140
				Perror2_exit("plumb: SIOCLIFADDIF", name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4141
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4142
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4143
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4144
		 * IP can create the new logical interface on a different
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4145
		 * physical interface in the same IPMP group. Take the new
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4146
		 * interface into account for further operations.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4147
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4148
		(void) strncpy(name, lifr.lifr_name, sizeof (name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4149
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4150
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4151
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4152
	if (debug)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4153
		(void) printf("inetplumb: %s af %d\n", name, afp->af_af);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4155
	if ((dev_fd = dlpi_if_open(name, &dia, _B_FALSE)) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4156
		Perror2_exit("plumb", name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4157
		/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4158
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4160
	plumb_one_device(&dia, dev_fd, afp->af_af);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4161
	(void) close(dev_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4162
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4163
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4165
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4166
Perror0(char *cmd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4167
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4168
	int save_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4170
	save_errno = errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4171
	(void) fprintf(stderr, "ifconfig: ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4172
	errno = save_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4173
	switch (errno) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4175
	case ENXIO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4176
		(void) fprintf(stderr, "%s: %s: no such interface\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4177
			cmd, lifr.lifr_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4178
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4179
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4180
	case EPERM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4181
		(void) fprintf(stderr, "%s: %s: permission denied\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4182
			cmd, lifr.lifr_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4183
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4184
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4185
	case EEXIST:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4186
		(void) fprintf(stderr, "%s: %s: already exists\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4187
			cmd, lifr.lifr_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4188
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4189
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4190
	default: {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4191
		char buf[BUFSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4193
		(void) snprintf(buf, sizeof (buf), "%s: %s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4194
		    cmd, lifr.lifr_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4195
		perror(buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4196
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4197
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4198
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4199
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4200
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4201
Perror0_exit(char *cmd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4202
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4203
	Perror0(cmd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4204
	exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4205
	/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4206
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4208
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4209
Perror2(char *cmd, char *str)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4210
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4211
	int save_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4212
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4213
	save_errno = errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4214
	(void) fprintf(stderr, "ifconfig: ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4215
	errno = save_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4216
	switch (errno) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4218
	case ENXIO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4219
		(void) fprintf(stderr, "%s: %s: no such interface\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4220
			cmd, str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4221
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4222
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4223
	case EPERM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4224
		(void) fprintf(stderr, "%s: %s: permission denied\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4225
			cmd, str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4226
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4228
	default: {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4229
		char buf[BUFSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4231
		(void) snprintf(buf, sizeof (buf), "%s: %s", cmd, str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4232
		perror(buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4233
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4234
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4235
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4237
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4238
 * Print out error message (Perror2()) and exit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4239
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4240
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4241
Perror2_exit(char *cmd, char *str)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4242
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4243
	Perror2(cmd, str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4244
	exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4245
	/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4246
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4247
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4248
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4249
 * If the last argument is non-NULL allow a <addr>/<n> syntax and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4250
 * pass out <n> in *plenp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4251
 * If <n> doesn't parse return BAD_ADDR as *plenp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4252
 * If no /<n> is present return NO_PREFIX as *plenp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4253
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4254
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4255
in_getaddr(char *s, struct sockaddr *saddr, int *plenp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4256
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4257
	struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4258
	struct hostent *hp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4259
	struct netent *np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4260
	char str[BUFSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4261
	int error_num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4262
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4263
	(void) strncpy(str, s, sizeof (str));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4265
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4266
	 * Look for '/'<n> is plenp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4267
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4268
	if (plenp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4269
		char *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4271
		*plenp = in_getprefixlen(str, _B_TRUE, ADDRBITS_V4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4272
		if (*plenp == BAD_ADDR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4273
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4274
		cp = strchr(str, '/');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4275
		if (cp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4276
			*cp = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4277
	} else if (strchr(str, '/') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4278
		(void) fprintf(stderr, "ifconfig: %s: unexpected '/'\n", str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4279
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4280
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4282
	(void) memset(sin, 0, sizeof (*sin));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4283
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4284
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4285
	 *	Try to catch attempts to set the broadcast address to all 1's.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4286
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4287
	if (strcmp(str, "255.255.255.255") == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4288
	    (strtoul(str, (char **)NULL, 0) == 0xffffffffUL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4289
		sin->sin_family = AF_INET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4290
		sin->sin_addr.s_addr = 0xffffffff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4291
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4292
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4294
	hp = getipnodebyname(str, AF_INET, 0, &error_num);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4295
	if (hp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4296
		sin->sin_family = hp->h_addrtype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4297
		(void) memcpy(&sin->sin_addr, hp->h_addr, hp->h_length);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4298
		freehostent(hp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4299
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4300
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4301
	np = getnetbyname(str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4302
	if (np) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4303
		sin->sin_family = np->n_addrtype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4304
		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4305
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4306
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4307
	if (error_num == TRY_AGAIN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4308
		(void) fprintf(stderr, "ifconfig: %s: bad address "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4309
		    "(try again later)\n", s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4310
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4311
		(void) fprintf(stderr, "ifconfig: %s: bad address\n", s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4312
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4313
	exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4314
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4316
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4317
 * If the last argument is non-NULL allow a <addr>/<n> syntax and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4318
 * pass out <n> in *plenp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4319
 * If <n> doesn't parse return BAD_ADDR as *plenp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4320
 * If no /<n> is present return NO_PREFIX as *plenp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4321
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4322
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4323
in6_getaddr(char *s, struct sockaddr *saddr, int *plenp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4324
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4325
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4326
	struct hostent *hp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4327
	char str[BUFSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4328
	int error_num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4330
	(void) strncpy(str, s, sizeof (str));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4331
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4332
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4333
	 * Look for '/'<n> is plenp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4334
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4335
	if (plenp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4336
		char *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4338
		*plenp = in_getprefixlen(str, _B_TRUE, ADDRBITS_V6);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4339
		if (*plenp == BAD_ADDR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4340
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4341
		cp = strchr(str, '/');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4342
		if (cp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4343
			*cp = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4344
	} else if (strchr(str, '/') != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4345
		(void) fprintf(stderr, "ifconfig: %s: unexpected '/'\n", str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4346
		exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4347
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4348
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4349
	(void) memset(sin6, 0, sizeof (*sin6));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4351
	hp = getipnodebyname(str, AF_INET6, 0, &error_num);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4352
	if (hp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4353
		sin6->sin6_family = hp->h_addrtype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4354
		(void) memcpy(&sin6->sin6_addr, hp->h_addr, hp->h_length);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4355
		freehostent(hp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4356
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4357
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4358
	if (error_num == TRY_AGAIN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4359
		(void) fprintf(stderr, "ifconfig: %s: bad address "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4360
		    "(try again later)\n", s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4361
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4362
		(void) fprintf(stderr, "ifconfig: %s: bad address\n", s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4363
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4364
	exit(1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4365
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4366
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4367
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4368
 * If "slash" is zero this parses the whole string as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4369
 * an integer. With "slash" non zero it parses the tail part as an integer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4370
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4371
 * If it is not a valid integer this returns BAD_ADDR.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4372
 * If there is /<n> present this returns NO_PREFIX.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4373
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4374
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4375
in_getprefixlen(char *addr, boolean_t slash, int max_plen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4376
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4377
	int prefixlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4378
	char *str, *end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4380
	if (slash) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4381
		str = strchr(addr, '/');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4382
		if (str == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4383
			return (NO_PREFIX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4384
		str++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4385
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4386
		str = addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4387
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4388
	prefixlen = strtol(str, &end, 10);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4389
	if (prefixlen < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4390
		return (BAD_ADDR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4391
	if (str == end)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4392
		return (BAD_ADDR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4393
	if (max_plen != 0 && max_plen < prefixlen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4394
		return (BAD_ADDR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4395
	return (prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4396
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4398
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4399
 * Convert a prefix length to a mask.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4400
 * Returns 1 if ok. 0 otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4401
 * Assumes the mask array is zero'ed by the caller.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4402
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4403
static boolean_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4404
in_prefixlentomask(int prefixlen, int maxlen, uchar_t *mask)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4405
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4406
	if (prefixlen < 0 || prefixlen > maxlen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4407
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4408
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4409
	while (prefixlen > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4410
		if (prefixlen >= 8) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4411
			*mask++ = 0xFF;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4412
			prefixlen -= 8;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4413
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4414
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4415
		*mask |= 1 << (8 - prefixlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4416
		prefixlen--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4417
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4418
	return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4419
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4420
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4421
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4422
print_flags(uint64_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4423
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4424
	boolean_t first = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4425
	int cnt, i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4426
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4427
	(void) printf("flags=%llx", flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4428
	cnt = sizeof (if_flags_tbl) / sizeof (if_flags_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4429
	for (i = 0; i < cnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4430
		if (flags & if_flags_tbl[i].iff_value) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4431
			if (first) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4432
				(void) printf("<");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4433
				first = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4434
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4435
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4436
				 * It has to be here and not with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4437
				 * printf below because for the last one,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4438
				 * we don't want a comma before the ">".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4439
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4440
				(void) printf(",");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4441
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4442
			(void) printf("%s", if_flags_tbl[i].iff_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4443
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4444
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4445
	if (!first)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4446
		(void) printf(">");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4447
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4449
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4450
print_config_flags(uint64_t flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4451
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4452
	int cnt, i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4454
	cnt = sizeof (if_config_cmd_tbl) / sizeof (if_config_cmd_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4455
	for (i = 0; i < cnt; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4456
		if (flags & if_config_cmd_tbl[i].iff_flag) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4457
			(void) printf("%s ", if_config_cmd_tbl[i].iff_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4458
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4459
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4460
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4461
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4462
/*
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4463
 * Use the configured directory lookup mechanism (e.g. files/NIS/NIS+/...)
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4464
 * to find the network mask.  Returns true if we found one to set.
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4465
 *
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4466
 * The parameter addr_set controls whether we should get the address of
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4467
 * the working interface for the netmask query.  If addr_set is true,
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4468
 * we will use the address provided.  Otherwise, we will find the working
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4469
 * interface's address and use it instead.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4470
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4471
static boolean_t
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4472
in_getmask(struct sockaddr_in *saddr, boolean_t addr_set)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4473
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4474
	struct sockaddr_in ifaddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4475
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4476
	/*
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4477
	 * Read the address from the interface if it is not passed in.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4478
	 */
198
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4479
	if (!addr_set) {
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4480
		(void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4481
		if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) < 0) {
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4482
			if (errno != EADDRNOTAVAIL) {
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4483
				(void) fprintf(stderr, "Need net number for "
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4484
				    "mask\n");
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4485
			}
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4486
			return (_B_FALSE);
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4487
		}
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4488
		ifaddr = *((struct sockaddr_in *)&lifr.lifr_addr);
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4489
	} else {
93f223a7d535 6249405 CIDR support does not work for logical interface
kcpoon
parents: 0
diff changeset
  4490
		ifaddr.sin_addr = saddr->sin_addr;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4491
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4492
	if (getnetmaskbyaddr(ifaddr.sin_addr, &saddr->sin_addr) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4493
		saddr->sin_family = AF_INET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4494
		return (_B_TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4495
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4496
	return (_B_FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4497
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4498
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4499
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4500
strioctl(int s, int cmd, char *buf, int buflen)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4501
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4502
	struct strioctl ioc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4503
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4504
	(void) memset(&ioc, 0, sizeof (ioc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4505
	ioc.ic_cmd = cmd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4506
	ioc.ic_timout = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4507
	ioc.ic_len = buflen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4508
	ioc.ic_dp = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4509
	return (ioctl(s, I_STR, (char *)&ioc));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4510
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4511
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4512
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4513
add_ni(char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4514
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4515
	ni_t **pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4516
	ni_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4517
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4518
	for (pp = &ni_list; (p = *pp) != NULL; pp = &(p->ni_next)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4519
		if (strcmp(p->ni_name, name) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4520
			if (debug > 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4521
				(void) fprintf(stderr, "'%s' is a duplicate\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4522
				    name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4523
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4524
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4525
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4527
	if (debug > 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4528
		(void) fprintf(stderr, "adding '%s'\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4529
		    name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4530
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4531
	if ((p = malloc(sizeof (ni_t))) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4532
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4533
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4534
	(void) strlcpy(p->ni_name, name, sizeof (p->ni_name));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4535
	p->ni_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4536
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4537
	*pp = p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4538
	num_ni++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4539
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4540
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4541
/* ARGSUSED2 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4542
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4543
devfs_entry(di_node_t node, di_minor_t minor, void *arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4544
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4545
	char *provider;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4546
	int fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4547
	uint_t ppa;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4548
	dl_info_ack_t dlia;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4549
	char ifname[LIFNAMSIZ];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4550
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4551
	provider = di_minor_name(minor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4552
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4553
	if (strlen(provider) > LIFNAMSIZ)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4554
		return (DI_WALK_CONTINUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4555
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4556
	if (debug > 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4557
		fprintf(stderr, "provider = %s\n", provider);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4559
	if ((fd = dlpi_open(provider)) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4560
		return (DI_WALK_CONTINUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4562
	if (debug > 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4563
		fprintf(stderr, "getting DL_INFO_ACK\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4564
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4565
	if (dlpi_info(fd, -1, &dlia, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4566
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4567
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4568
	if (dlia.dl_provider_style == DL_STYLE1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4569
		if (debug > 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4570
			fprintf(stderr, "provider is DL_STYLE1\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4571
		add_ni(provider);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4572
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4573
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4574
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4575
	if (debug > 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4576
		fprintf(stderr, "provider is DL_STYLE2\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4577
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4578
	if (di_minor_type(minor) != DDM_ALIAS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4579
		if (debug > 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4580
			(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4581
			    "non-alias node, ignoring\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4582
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4583
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4585
	if (debug > 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4586
		(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4587
		    "alias node, using instance\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4588
	ppa = di_instance(node);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4589
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4590
	if (dlpi_attach(fd, -1, ppa) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4591
		if (debug > 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4592
			(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4593
			    "non-existent PPA, ignoring\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4594
		goto done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4595
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4596
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4597
	(void) snprintf(ifname, LIFNAMSIZ, "%s%d", provider, ppa);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4598
	add_ni(ifname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4599
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4600
done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4601
	(void) dlpi_close(fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4602
	return (DI_WALK_CONTINUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4603
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4604
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4605
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4606
 * dhcp-related routines
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4607
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4608
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4609
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4610
setifdhcp(const char *caller, const char *ifname, int argc, char *argv[])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4611
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4612
	dhcp_ipc_request_t	*request;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4613
	dhcp_ipc_reply_t	*reply	= NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4614
	int			timeout = DHCP_IPC_WAIT_DEFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4615
	dhcp_ipc_type_t		type	= DHCP_START;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4616
	int			error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4617
	boolean_t		is_primary = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4618
	boolean_t		started = _B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4620
	for (argv++; --argc > 0; argv++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4621
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4622
		if (strcmp(*argv, "primary") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4623
			is_primary = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4624
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4625
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4627
		if (strcmp(*argv, "wait") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4628
			if (--argc <= 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4629
				usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4630
				return (DHCP_EXIT_BADARGS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4631
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4632
			argv++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4633
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4634
			if (strcmp(*argv, "forever") == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4635
				timeout = DHCP_IPC_WAIT_FOREVER;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4636
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4637
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4638
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4639
			if (sscanf(*argv, "%d", &timeout) != 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4640
				usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4641
				return (DHCP_EXIT_BADARGS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4642
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4644
			if (timeout < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4645
				usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4646
				return (DHCP_EXIT_BADARGS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4647
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4648
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4649
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4650
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4651
		type = dhcp_string_to_request(*argv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4652
		if (type == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4653
			usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4654
			return (DHCP_EXIT_BADARGS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4655
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4656
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4658
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4659
	 * Only try to start agent on start or inform; in all other cases it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4660
	 * has to already be running for anything to make sense.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4661
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4662
	if (type == DHCP_START || type == DHCP_INFORM) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4663
		if (dhcp_start_agent(DHCP_IPC_MAX_WAIT) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4664
			(void) fprintf(stderr, "%s: unable to start %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4665
			    caller, DHCP_AGENT_PATH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4666
			return (DHCP_EXIT_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4667
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4668
		started = _B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4669
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4670
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4671
	if (is_primary)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4672
		type = type | DHCP_PRIMARY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4673
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4674
	request = dhcp_ipc_alloc_request(type, ifname, NULL, 0, DHCP_TYPE_NONE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4675
	if (request == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4676
		(void) fprintf(stderr, "%s: out of memory\n", caller);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4677
		return (DHCP_EXIT_SYSTEM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4678
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4679
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4680
	error = dhcp_ipc_make_request(request, &reply, timeout);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4681
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4682
		free(request);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4683
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4684
		 * Re-map connect error to not under control if we didn't try a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4685
		 * start operation, as this has to be true and results in a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4686
		 * clearer message, not to mention preserving compatibility
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4687
		 * with the days when we always started dhcpagent for every
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4688
		 * request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4689
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4690
		if (error == DHCP_IPC_E_CONNECT && !started)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4691
			error = DHCP_IPC_E_UNKIF;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4692
		(void) fprintf(stderr, "%s: %s: %s\n", caller, ifname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4693
		    dhcp_ipc_strerror(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4694
		return (DHCP_EXIT_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4695
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4696
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4697
	error = reply->return_code;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4698
	if (error != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4699
		free(request);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4700
		free(reply);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4701
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4702
		if (error == DHCP_IPC_E_TIMEOUT && timeout == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4703
			return (DHCP_EXIT_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4705
		(void) fprintf(stderr, "%s: %s: %s\n", caller, ifname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4706
		    dhcp_ipc_strerror(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4707
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4708
		if (error == DHCP_IPC_E_TIMEOUT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4709
			return (DHCP_EXIT_TIMEOUT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4710
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4711
			return (DHCP_EXIT_IF_FAILURE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4712
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4714
	if (DHCP_IPC_CMD(type) == DHCP_STATUS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4715
		(void) printf("%s", dhcp_status_hdr_string());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4716
		(void) printf("%s", dhcp_status_reply_to_string(reply));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4717
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4719
	free(request);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4720
	free(reply);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4721
	return (DHCP_EXIT_SUCCESS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4722
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4723
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4724
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4725
usage(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4726
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4727
	(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4728
	    "usage: ifconfig <interface> | -a[ 4 | 6 | D ][ u | d ][ Z ]\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4730
	(void) fprintf(stderr, "%s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4731
	    "\t[ <addr_family> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4732
	    "\t[ <address>[/<prefix_length>] [ <dest_address> ] ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4733
	    "\t[ set [ <address>][/<prefix_length>] ]"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4734
	    " [ <address>/<prefix_length>] ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4735
	    "\t[ destination <dest_address> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4736
	    "\t[ addif <address>[/<prefix_length>]"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4737
	    "  [ <dest_address> ] ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4738
	    "\t[ removeif <address>[/<prefix_length>] ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4739
	    "\t[ arp | -arp ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4740
	    "\t[ auto-revarp ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4741
	    "\t[ broadcast <broad_addr> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4742
	    "\t[ index <if_index> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4743
	    "\t[ metric <n> ] [ mtu <n> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4744
	    "\t[ netmask <mask> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4745
	    "\t[ plumb ] [ unplumb ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4746
	    "\t[ preferred | -preferred ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4747
	    "\t[ private | -private ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4748
	    "\t[ local | -local ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4749
	    "\t[ router | -router ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4750
	    "\t[ subnet <subnet_address>]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4751
	    "\t[ trailers | -trailers ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4752
	    "\t[ token <address>/<prefix_length> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4753
	    "\t[ tsrc <tunnel_src_address> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4754
	    "\t[ tdst <tunnel_dest_address> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4755
	    "\t[ auth_algs <tunnel_AH_authentication_algorithm> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4756
	    "\t[ encr_algs <tunnel_ESP_encryption_algorithm> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4757
	    "\t[ encr_auth_algs <tunnel_ESP_authentication_algorithm> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4758
	    "\t[ up ] [ down ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4759
	    "\t[ xmit | -xmit ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4760
	    "\t[ modlist ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4761
	    "\t[ modinsert <module_name@position> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4762
	    "\t[ modremove <module_name@position> ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4763
	    "\t[ group <groupname>] | [ group \"\"]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4764
	    "\t[ deprecated | -deprecated ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4765
	    "\t[ standby | -standby ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4766
	    "\t[ failover | -failover ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4767
	    "\t[ zone <zonename> | -zone ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4768
	    "\t[ usesrc <interface> ]\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4770
	(void) fprintf(stderr, "or\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4771
	(void) fprintf(stderr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4772
	    "\tifconfig <interface> |  -a[ 4 | 6 | D ] [ u | d ]\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4773
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4774
	(void) fprintf(stderr, "%s", "\tauto-dhcp | dhcp\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4775
	    "\t[ wait <time> | forever ]\n\t[ primary ]\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4776
	    "\tstart | drop | ping | release | status | inform\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4777
}