xref: /freebsd/usr.sbin/bsdconfig/networking/share/device.subr (revision 34f9b7199d70df0ff5616621c43998eb09d9dea5)
1if [ ! "$_NETWORKING_DEVICE_SUBR" ]; then _NETWORKING_DEVICE_SUBR=1
2#
3# Copyright (c) 2006-2012 Devin Teske
4# All Rights Reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD$
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_include $BSDCFG_SHARE/dialog.subr
34f_include $BSDCFG_SHARE/sysrc.subr
35f_include $BSDCFG_SHARE/networking/common.subr
36f_include $BSDCFG_SHARE/networking/ipaddr.subr
37f_include $BSDCFG_SHARE/networking/media.subr
38f_include $BSDCFG_SHARE/networking/netmask.subr
39f_include $BSDCFG_SHARE/networking/resolv.subr
40f_include $BSDCFG_SHARE/networking/routing.subr
41
42BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="120.networking"
43f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
44
45TCP_HELPFILE=$BSDCFG_LIBE/$APP_DIR/include/tcp.hlp
46
47############################################################ GLOBALS
48
49#
50# Settings used while interacting with various dialog(1) menus
51#
52: ${DIALOG_MENU_NETDEV_KICK_INTERFACES=1}
53: ${DIALOG_MENU_NETDEV_SLEEP_AFTER_KICK=3}
54
55############################################################ FUNCTIONS
56
57# f_device_desc $device_name
58#
59# Print a description for a device name (eg., `fxp0').
60#
61f_device_desc()
62{
63	local device="$1" d="[1234567890]" desc=""
64
65	# Check variables
66	[ "$device" ] || return $SUCCESS
67
68	#
69	# Return sysctl MIB dev.NAME.UNIT.%desc if it exists,
70	# otherwise fall through to below static list.
71	#
72	if f_have sysctl; then
73		local devname devunit
74		devname="${device%%$d*}"
75		devunit="${device#$devname}"
76		devunit="${devunit%%[a-zA-Z_]*}"
77		sysctl -n "dev.$devname.$devunit.%desc" 2> /dev/null &&
78			return $SUCCESS
79	fi
80
81	case "$device" in
82	# Network devices
83	ae$d)    desc="Attansic/Atheros L2 Fast Ethernet";;
84	age$d)   desc="Attansic/Atheros L1 Gigabit Ethernet";;
85	alc$d)   desc="Atheros AR8131/AR8132 PCIe Ethernet";;
86	ale$d)   desc="Atheros AR8121/AR8113/AR8114 PCIe Ethernet";;
87	an$d)    desc="Aironet 4500/4800 802.11 wireless adapter";;
88	ath$d)   desc="Atheros IEEE 802.11 wireless adapter";;
89	aue$d)   desc="ADMtek USB Ethernet adapter";;
90	axe$d)   desc="ASIX Electronics USB Ethernet adapter";;
91	bce$d)   desc="Broadcom NetXtreme II Gigabit Ethernet card";;
92	bfe$d)   desc="Broadcom BCM440x PCI Ethernet card";;
93	bge$d)   desc="Broadcom BCM570x PCI Gigabit Ethernet card";;
94	bm$d)    desc="Apple BMAC Built-in Ethernet";;
95	bwn$d)   desc="Broadcom BCM43xx IEEE 802.11 wireless adapter";;
96	cas$d)   desc="Sun Cassini/Cassini+ or NS DP83065 Saturn Ethernet";;
97	cc3i$d)  desc="SDL HSSI sync serial PCI card";;
98	cue$d)   desc="CATC USB Ethernet adapter";;
99	cxgb$d)  desc="Chelsio T3 10Gb Ethernet card";;
100	dc$d)    desc="DEC/Intel 21143 (and clones) PCI Fast Ethernet card";;
101	de$d)    desc="DEC DE435 PCI NIC or other DC21040-AA based card";;
102	disc$d)  desc="Software discard network interface";;
103	ed$d)    desc="Novell NE1000/2000; 3C503; NE2000-compatible PCMCIA";;
104	el$d)    desc="3Com 3C501 Ethernet card";;
105	em$d)    desc="Intel(R) PRO/1000 Ethernet card";;
106	en$d)    desc="Efficient Networks ATM PCI card";;
107	ep$d)    desc="3Com 3C509 Ethernet card/3C589 PCMCIA";;
108	et$d)    desc="Agere ET1310 based PCI Express Gigabit Ethernet card";;
109	ex$d)    desc="Intel EtherExpress Pro/10 Ethernet card";;
110	fe$d)    desc="Fujitsu MB86960A/MB86965A Ethernet card";;
111	fpa$d)   desc="DEC DEFPA PCI FDDI card";;
112	fwe$d)   desc="FireWire Ethernet emulation";;
113	fwip$d)  desc="IP over FireWire";;
114	fxp$d)   desc="Intel EtherExpress Pro/100B PCI Fast Ethernet card";;
115	gem$d)   desc="Apple GMAC or Sun ERI/GEM Ethernet adapter";;
116	hme$d)   desc="Sun HME (Happy Meal Ethernet) Ethernet adapter";;
117	ie$d)    desc="AT&T StarLAN 10 and EN100; 3Com 3C507; NI5210";;
118	igb$d)   desc="Intel(R) PRO/1000 PCI Express Gigabit Ethernet card";;
119	ipw$d)   desc="Intel PRO/Wireless 2100 IEEE 802.11 adapter";;
120	iwi$d)   desc="Intel PRO/Wireless 2200BG/2225BG/2915ABG adapter";;
121	iwn$d)   desc="Intel Wireless WiFi Link 4965AGN IEEE 802.11n adapter";;
122	ix$d)    desc="Intel Etherexpress Ethernet card";;
123	ixgb$d)  desc="Intel(R) PRO/10Gb Ethernet card";;
124	ixgbe$d) desc="Intel(R) PRO/10Gb Ethernet card";;
125	jme$d)   desc="JMicron JMC250 Gigabit/JMC260 Fast Ethernet";;
126	kue$d)   desc="Kawasaki LSI USB Ethernet adapter";;
127	le$d)    desc="AMD Am7900 LANCE or Am79C9xx PCnet Ethernet adapter";;
128	lge$d)   desc="Level 1 LXT1001 Gigabit Ethernet card";;
129	lnc$d)   desc="Lance/PCnet (Isolan/Novell NE2100/NE32-VL) Ethernet";;
130	lp$d)    desc="Parallel Port IP (PLIP) peer connection";;
131	lo$d)    desc="Loop-back (local) network interface";;
132	malo$d)  desc="Marvell Libertas 88W8335 802.11 wireless adapter";;
133	msk$d)   desc="Marvell/SysKonnect Yukon II Gigabit Ethernet";;
134	mxge$d)  desc="Myricom Myri10GE 10Gb Ethernet card";;
135	nfe$d)   desc="NVIDIA nForce MCP Ethernet";;
136	ng${d}_*|ng$d${d}_*|ng$d$d${d}_*|ng$d$d$d${d}_*|ng$d$d$d$d${d}_*)
137	         desc="Vimage netgraph(4) bridged Ethernet device";;
138	nge$d)   desc="NatSemi PCI Gigabit Ethernet card";;
139	nve$d)   desc="NVIDIA nForce MCP Ethernet";;
140	nxge$d)  desc="Neterion Xframe 10GbE Server/Storage adapter";;
141	pcn$d)   desc="AMD Am79c79x PCI Ethernet card";;
142	plip$d)  desc="Parallel Port IP (PLIP) peer connection";;
143	ral$d)   desc="Ralink Technology IEEE 802.11 wireless adapter";;
144	ray$d)   desc="Raytheon Raylink 802.11 wireless adapter";;
145	re$d)    desc="RealTek 8139C+/8169/8169S/8110S PCI Ethernet adapter";;
146	rl$d)    desc="RealTek 8129/8139 PCI Ethernet card";;
147	rue$d)   desc="RealTek USB Ethernet card";;
148	rum$d)   desc="Ralink Technology USB IEEE 802.11 wireless adapter";;
149	sf$d)    desc="Adaptec AIC-6915 PCI Ethernet card";;
150	sge$d)   desc="Silicon Integrated Systems SiS190/191 Ethernet";;
151	sis$d)   desc="SiS 900/SiS 7016 PCI Ethernet card";;
152	sk$d)    desc="SysKonnect PCI Gigabit Ethernet card";;
153	sn$d)    desc="SMC/Megahertz Ethernet card";;
154	snc$d)   desc="SONIC Ethernet card";;
155	sr$d)    desc="SDL T1/E1 sync serial PCI card";;
156	ste$d)   desc="Sundance ST201 PCI Ethernet card";;
157	stge$d)  desc="Sundance/Tamarack TC9021 Gigabit Ethernet";;
158	ti$d)    desc="Alteon Networks PCI Gigabit Ethernet card";;
159	tl$d)    desc="Texas Instruments ThunderLAN PCI Ethernet card";;
160	tx$d)    desc="SMC 9432TX Ethernet card";;
161	txp$d)   desc="3Com 3cR990 Ethernet card";;
162	uath$d)  desc="Atheros AR5005UG and AR5005UX USB wireless adapter";;
163	upgt$d)  desc="Conexant/Intersil PrismGT USB wireless adapter";;
164	ural$d)  desc="Ralink Technology RT2500USB 802.11 wireless adapter";;
165	urtw$d)  desc="Realtek 8187L USB wireless adapter";;
166	vge$d)   desc="VIA VT612x PCI Gigabit Ethernet card";;
167	vlan$d|vlan$d$d|vlan$d$d$d|vlan$d$d$d$d|vlan$d$d$d$d$d)
168	         desc="IEEE 802.1Q VLAN network interface";;
169	vr$d)    desc="VIA VT3043/VT86C100A Rhine PCI Ethernet card";;
170	vx$d)    desc="3COM 3c590 / 3c595 Ethernet card";;
171	wb$d)    desc="Winbond W89C840F PCI Ethernet card";;
172	wi$d)    desc="Lucent WaveLAN/IEEE 802.11 wireless adapter";;
173	wpi$d)   desc="Intel 3945ABG IEEE 802.11 wireless adapter";;
174	wx$d)    desc="Intel Gigabit Ethernet (82452) card";;
175	xe$d)    desc="Xircom/Intel EtherExpress Pro100/16 Ethernet card";;
176	xl$d)    desc="3COM 3c90x / 3c90xB PCI Ethernet card";;
177	zyd$d)   desc="ZyDAS ZD1211/ZD1211B USB 802.11 wireless adapter";;
178	# Unknown device
179	*)       desc="<unknown network interface type>";;
180	esac
181	printf "%s\n" "$desc"
182}
183
184# f_dialog_menu_netdev
185#
186# Display a list of network devices with descriptions.
187#
188f_dialog_menu_netdev()
189{
190	#
191	# Display a message to let the user know we're working...
192	# (message will remain until we throw up the next dialog)
193	#
194	f_dialog_info "$msg_probing_network_interfaces"
195
196	#
197	# Get list of usable network interfaces
198	#
199	local d='[[:digit:]]+:'
200	local iflist="`echo "$(ifconfig -l):" | sed -E -e "
201		# Convert all spaces to colons
202		y/ /:/
203
204		# Prune unsavory interfaces
205		s/lo$d//g
206		s/ppp$d//g
207		s/sl$d//g
208		s/faith$d//g
209
210		# Convert all colons back into spaces
211		y/:/ /
212	"`"
213
214	#
215	# Optionally kick interfaces in the head to get them to accurately
216	# track the carrier status in realtime (required on FreeBSD).
217	#
218	if [ "$DIALOG_MENU_NETDEV_KICK_INTERFACES" ]; then
219		DIALOG_MENU_NETDEV_KICK_INTERFACES=
220
221		local ifn
222		for ifn in $iflist; do
223			f_quietly ifconfig $ifn up
224		done
225
226		if [ "$DIALOG_MENU_NETDEV_SLEEP_AFTER_KICK" ]; then
227			# interfaces need time to update carrier status
228			sleep $DIALOG_MENU_NETDEV_SLEEP_AFTER_KICK
229		fi
230	fi
231
232	#
233	# Mark any "active" interfaces with an asterisk (*)
234	# to the right of the device name.
235	#
236	interfaces=$(
237		for ifn in $iflist; do
238			active=$( ifconfig $ifn | awk \
239			'
240				( $1 == "status:" ) \
241				{
242					if ( $2 == "active" ) { print 1; exit }
243				}
244			' )
245			printf "'%s%s' '%s'\n" \
246				$ifn "${active:+*}" "$( f_device_desc $ifn )"
247		done
248	)
249	if [ ! "$interfaces" ]; then
250		f_dialog_msgbox "$msg_no_network_interfaces"
251		return $FAILURE
252	fi
253
254	local hline="$hline_arrows_tab_enter"
255
256	#
257	# Ask user to select an interface
258	#
259	local prompt size
260	prompt="$msg_select_network_interface"
261	size=$( eval f_dialog_menu_size \
262	        	\"\$DIALOG_TITLE\"     \
263	        	\"\$DIALOG_BACKTITLE\" \
264	        	\"\$prompt\"           \
265	        	\"\$hline\"            \
266	        	$interfaces            )
267	local dialog_menu
268	dialog_menu=$( eval $DIALOG \
269		--clear --title \"\$DIALOG_TITLE\" \
270		--backtitle \"\$DIALOG_BACKTITLE\" \
271		--hline \"\$hline\"                \
272		--ok-label \"\$msg_ok\"            \
273		--cancel-label \"\$msg_cancel\"    \
274		--menu \"\$prompt\" $size          \
275		$interfaces                        \
276		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
277	)
278	local retval=$?
279	setvar DIALOG_MENU_$$ "$dialog_menu"
280	return $retval
281}
282
283# f_dialog_menu_netdev_edit $interface $ipaddr $netmask $options $dhcp
284#
285# Allow a user to edit network interface settings. Current values are not
286# probed but rather taken from the positional arguments.
287#
288f_dialog_menu_netdev_edit()
289{
290	local interface="$1" ipaddr="$2" netmask="$3" options="$4" dhcp="$5"
291	local prompt menu_list size
292
293	#
294	# Create a duplicate set of variables for change-tracking...
295	#
296	local ipaddr_orig="$2"  \
297	      netmask_orig="$3" \
298	      options_orig="$4" \
299	      dhcp_orig="$5"
300
301	local hline="$hline_arrows_tab_enter"
302	prompt=$( printf "$msg_network_configuration" "$interface" )
303
304	#
305	# Loop forever until the user has finished configuring the different
306	# components of the network interface.
307	#
308	# To apply the settings, we need to know each of the following:
309	# 	- IP Address
310	# 	- Network subnet mask
311	# 	- Additional ifconfig(8) options
312	#
313	# It is only when we have all of the above values that we can make the
314	# changes effective because all three options must be specified at-once
315	# to ifconfig(8).
316	#
317	while :; do
318		local dhcp_status="$msg_disabled"
319		[ "$dhcp" ] && dhcp_status="$msg_enabled"
320
321		#
322		# Display configuration-edit menu
323		#
324		menu_list="
325			'X $msg_save_exit' '$msg_return_to_previous_menu'
326			'2 $msg_dhcp'      '$dhcp_status'
327			'3 $msg_ipaddr4'   '$ipaddr'
328			'4 $msg_netmask'   '$netmask'
329			'5 $msg_options'   '$options'
330		"
331		size=$( eval f_dialog_menu_size \
332		        	\"\$DIALOG_TITLE\"     \
333		        	\"\$DIALOG_BACKTITLE\" \
334		        	\"\$prompt\"           \
335		        	\"\$hline\"            \
336		        	$menu_list             )
337		local dialog_menu
338		dialog_menu=$( eval $DIALOG \
339			--clear --title \"\$DIALOG_TITLE\" \
340			--backtitle \"\$DIALOG_BACKTITLE\" \
341			--hline \"\$hline\"                \
342			--ok-label \"\$msg_ok\"            \
343			--cancel-label \"\$msg_cancel\"    \
344			--help-button                      \
345			${USE_XDIALOG:+--help \"\"}        \
346			--menu \"\$prompt\" $size          \
347			$menu_list                         \
348			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
349		)
350
351		local retval=$?
352		setvar DIALOG_MENU_$$ "$dialog_menu"
353		local tag="$( f_dialog_menutag )"
354
355		if [ $retval -eq 2 ]; then
356			# The Help button was pressed
357			f_show_help "$TCP_HELPFILE"
358			continue
359		elif [ $retval -ne $SUCCESS ]; then
360			# "Cancel" was chosen (-1) or ESC was pressed (255)
361			return $retval
362		fi
363
364		#
365		# Call the below ``modifier functions'' whose job it is to take
366		# input from the user and assign the newly-acquired values back
367		# to the ipaddr, netmask, and options variables for us to re-
368		# read and display in the summary dialog.
369		#
370		case "$tag" in
371		X\ *) break;;
372		2\ *) #
373		      # Do not proceed if/when there are NFS-mounts currently
374		      # active. If the network is changed while NFS-exported
375		      # directories are mounted, the system may hang (if any
376		      # NFS mounts are using that interface).
377		      #
378		      if f_nfs_mounted && ! f_jailed; then
379		      	local setting="$( printf "$msg_current_dhcp_status" \
380		      	                         "$interface" "$dhcp_status" )"
381			f_show_msg "$msg_nfs_mounts_may_cause_hang" "$setting"
382		      	continue
383		      fi
384
385		      #
386		      # Toggle DHCP status
387		      #
388		      if [ "$dhcp_status" = "$msg_enabled" ]; then
389		      	dhcp=
390		      else
391		      	trap - SIGINT
392		      	( # Execute within sub-shell to allow/catch Ctrl-C
393		      	  trap 'exit $FAILURE' SIGINT
394		      	  msg=$( printf "$msg_scanning_for_dhcp" "$interface" )
395		      	  if [ "$USE_XDIALOG" ]; then
396		      	  	(
397		      	  	  f_quietly ifconfig $interface delete
398		      	  	  f_quietly dhclient $interface
399		      	  	) |
400		      	  	  f_xdialog_info "$msg"
401		      	  else
402		      	  	f_dialog_info "$msg"
403		      	  	f_quietly ifconfig $interface delete
404		      	  	f_quietly dhclient $interface
405		      	  fi
406		      	)
407		      	retval=$?
408		      	trap 'interrupt' SIGINT
409		      	if [ $retval -eq $SUCCESS ]; then
410		      		dhcp=1
411		      		ipaddr=$( f_ifconfig_inet $interface )
412		      		netmask=$( f_ifconfig_netmask $interface )
413		      		options=
414
415		      		# Fixup search/domain in resolv.conf(5)
416		      		hostname=$( f_sysrc_get \
417				            	'hostname:-$(hostname)' )
418		      		f_dialog_resolv_conf_update "$hostname"
419		      	fi
420		      fi
421		      ;;
422		3\ *) f_dialog_input_ipaddr "$interface" "$ipaddr"
423		      [ $? -eq $SUCCESS ] && dhcp=;;
424		4\ *) f_dialog_input_netmask "$interface" "$netmask"
425		      [ $? -eq $SUCCESS -a "$_netmask" ] && dhcp=;;
426		5\ *) f_dialog_menu_media_options "$interface" "$options"
427		      [ $? -eq $SUCCESS ] && dhcp=;;
428		esac
429	done
430
431	#
432	# Save only if the user changed at least one feature of the interface
433	#
434	if [ "$ipaddr"  != "$ipaddr_orig"  -o \
435	     "$netmask" != "$netmask_orig" -o \
436	     "$options" != "$options_orig" -o \
437	     "$dhcp"    != "$dhcp_orig" ]
438	then
439		f_show_info "$msg_saving_network_interface" "$interface"
440
441		local value=
442		if [ "$dhcp" ]; then
443			f_sysrc_delete defaultrouter
444			value=DHCP
445		else
446			value="inet $ipaddr netmask $netmask"
447			value="$value${options:+ }$options"
448		fi
449
450		f_sysrc_set ifconfig_$interface "$value"
451	fi
452
453	#
454	# Re/Apply the settings if desired
455	#
456	if [ ! "$dhcp" ]; then
457		f_dialog_yesno "Would you like to bring the $interface" \
458		               "interface up right now?"
459		if [ $? -eq $SUCCESS ]; then
460			f_show_info "$msg_bring_interface_up" "$interface"
461
462			local dr="$( f_sysrc_get defaultrouter )" err
463			if [ "$dr" = "NO" -o ! "$dr" ]; then
464				dr=$( f_route_get_default )
465				[ "$dr" ] && f_sysrc_set defaultrouter "$dr"
466			fi
467			#
468			# Make a backup of resolv.conf(5) before using
469			# ifconfig(8) and then restore it afterward. This
470			# allows preservation of nameservers acquired via
471			# DHCP on FreeBSD-8.x (normally lost as ifconfig(8)
472			# usage causes dhclient(8) to exit which scrubs
473			# resolv.conf(5) by-default upon termination).
474			#
475			f_quietly cp -fp "$RESOLV_CONF" "$RESOLV_CONF.$$"
476			err=$( ifconfig $interface inet $ipaddr \
477			       	netmask $netmask $options 2>&1 )
478			if [ $? -eq $SUCCESS ]; then
479				if [ "$dr" -a "$dr" != "NO" ]; then
480					err=$( route add default "$dr" 2>&1 )
481					[ $? -eq $SUCCESS ] || \
482						dialog_msgbox "$err"
483				fi
484			else
485				dialog_msgbox "$err"
486			fi
487			if cmp -s "$RESOLV_CONF" "$RESOLV_CONF.$$"; then
488				f_quietly rm -f "$RESOLV_CONF.$$"
489			else
490				f_quietly mv -f "$RESOLV_CONF.$$" "$RESOLV_CONF"
491			fi
492		fi
493	fi
494
495	return $SUCCESS
496}
497
498fi # ! $_NETWORKING_DEVICE_SUBR
499