#!/bin/sh ############################## # ************************************************************ # AltEPG Project Source Code Version Control # $FileID: git::root/sbin/nic_config_tivo $ # $Revision: altepg1.0c root 2011-09-17 23:39:32 +0100 Finalising altepg1.0c $ # Description: nic configuration script # ************************************************************ # # nic_config_tivo: Read /etc/oztivo.conf, allow user to change it, # write it back and also write /etc/rc.d/rc.net. # Written by Warren Toomey, wkt@tuhs.org # based on code by Simon Quigley, squigley@nyip.net # Some edits and corrections by petestrash # Further revisions by UK AltEPG project # # $Revision: altepg1.0c root 2011-09-17 23:39:32 +0100 Finalising altepg1.0c $ # ############################## Version="unconfigured" # # Settings file to store the configuration from the menu settings="/etc/oztivo.conf" tmpsettings="/tmp/oztivo.conf" # dhclient.conf (dhcp hostname) dhclient="/etc/dhclient.conf" # modem settings: # modem config file tclient="/etc/tclient.conf" # modem dialup files chapsec="/etc/chap-secrets" papsec="/etc/pap-secrets" pppops="/etc/ppp-options" # dialconfig number dialconfig=127 # These are the variables written out to the $settings file # and their default settings nic=Auto ip=DHCP mac=00:0B:AD:10:10:10 timing=16 hostname=altepgtivo emulator=194.1.151.205 emulatorport=80 netmask=255.255.255.0 gateway= ssid= wep= wepkey= # Other variables device="" # If set, we're running on the install CD rootpart=4 # active root partition, eg /dev/hda4 mountpoint=/mnt/tivo # Where to mount the tivo disk if install CD backtitle="AltEPG TiVo Network Configuration altepg1.0c" # Menu title updated="" # External Programs: need to change when running on CD dialog=/devbin/dialog mkdir=/bin/mkdir mount=/bin/mount umount=/bin/umount hdparm="/sbin/hdparm -q" # hdparm enable/disable dma reread="/tivobin/reread" # reread util, workaround for DMA # disable/byteswap enable issues ############################## # # display a fatal message to the user # fatal() { $dialog --backtitle "$backtitle" --title "Fatal Error" --clear --msgbox \ "\n Error!\n\nThe installation program has suffered this fatal error:\n\n$1\n\nThe installer will now exit. Please visit http://www.altepg.com/forum and provide details of the error." 17 60 rm -f /tmp/*.$$ $dialog --clear; stty sane; exit 1 } # # choose a random MAC address # random_macaddr() { mac1=`expr '(' $RANDOM '%' 90 ')' + 10` xyx=$RANDOM; xyx=$RANDOM; xyx=$RANDOM; mac2=`expr '(' $RANDOM '%' 90 ')' + 10` xyx=$RANDOM; xyx=$RANDOM; xyx=$RANDOM; mac3=`expr '(' $RANDOM '%' 90 ')' + 10` mac="00:0B:AD:$mac1:$mac2:$mac3" } # # send warning about SiliconDust installer cachecard_warning() { $dialog --backtitle "$backtitle" --title "Cachecard Warning" --msgbox \ "\n Warning!\n\nIf at some point in the future you decide to change to a Turbonet (or Equivalent) or Cachecard, do NOT use the Silicondust installer as it will damage the image on your disk and may not be easily recoverable. YOU HAVE BEEN WARNED !!!\n\nIf at some point in the future you wish to change your networking options, then please do so using this installer." 17 60 } # # Write the $settings file # write_settings() { echo "# AltEPG TiVo menu configuration settings file altepg1.0c" > $tmpsettings || \ fatal "Could not write to $tmpsettings" echo "# Please do not edit this file" >> $tmpsettings echo "# Run the nic_config_tivo tool to reconfigure" >> $tmpsettings echo "nic=$nic" >> $tmpsettings echo "ip=$ip" >> $tmpsettings echo "mac=$mac" >> $tmpsettings echo "timing=$timing" >> $tmpsettings echo "hostname=$hostname" >> $tmpsettings echo "emulator=$emulator" >> $tmpsettings echo "emulatorport=$emulatorport" >> $tmpsettings echo "netmask=$netmask" >> $tmpsettings echo "gateway=$gateway" >> $tmpsettings echo "ssid=$ssid" >> $tmpsettings echo "wep=$wep" >> $tmpsettings echo "wepkey=$wepkey" >> $tmpsettings cp $tmpsettings $settings || fatal "Could not copy $tmpsettings to $settings" rm -f $tmpsettings updated="yes" } # ############################## # Mounts the first selected device. # No functionality for mounting second device, but shouldn't need to # mount_disk() { # get the byteswapping current setting byteswap=`grep bswap /proc/ide/$device/settings|awk '{ print $2 }'` if [ "$byteswap" -ne "1" ]; then # not byteswapped. eek. # tell the user to pass the kernel parameter, hope it works. $dialog --backtitle "$backtitle" --title "Error" --msgbox \ "Unable to mount /dev/$device.\n\nByteswapping is not enabled on this device.\n\nReboot, and specify \"knoppix $device=swapdata\" at the \"kernel:\" prompt" 10 75 $dialog --clear; stty sane; exit 1 fi # we're ok to mount it # check the mount point exists if [ ! -d $mountpoint ]; then $mkdir -p $mountpoint if [ ! -d $mountpoint ]; then # unable to make the directory fatal "Unable to create mount point directory $mountpoint." fi fi # make sure DMA and write caching are disabled $hdparm -d0 -W0 /dev/$device # reread the partition table, in case of dodgy kernel parameter handling $reread $device || fatal "$reread $device failed" # now mount the device, with caching disabled $mount -o sync /dev/$device$rootpart $mountpoint 2>&1 >/tmp/mount if [ "$?" == "0" ]; then # mount executed successfully # check for the oztivo.conf file if [ ! -s "$settings" ]; then # no file, create basic one write_settings sync; sync fi else # an error occured mounting. eek. fatal "An error occurred mounting the device:\n`cat /tmp/mount`" fi } ############################## # # Unmounts the selected device umount_disk() { # flush the cache (even though mounted in sync mode) sync; sync; sync # Get hdparm to flush the on-drive cache $hdparm -f /dev/$device # now unmount $umount $mountpoint || fatal "Unable to unmount $mountpoint" } # # Enable device: either sets disk rw, or mounts it enable_device() { if [ -z $device ]; then /hack/bin/makerw.sh else mount_disk fi } # # Disable device: either sets disk ro, or unmounts it disable_device() { if [ -z $device ]; then /hack/bin/makero.sh else umount_disk fi } # # Display the current oztivo.conf # view_net_conf() { if [ "$updated" == "yes" ]; then # tell user the config has been changed $dialog --backtitle "$backtitle" --title "Configuration Changed" \ --msgbox "The network configuration has been changed.\nThe following screen will show the new configuration.\nVerify it is correct.\n(Use the left/right arrows to scroll)" 10 60 # reset the updated variable so we don't see this dialog again (unless the user updates something else) updated="" fi # display file $dialog --backtitle "$backtitle" --title "oztivo.conf" --textbox $settings 20 60 } ############################## # pppondss_conf() # configures the tivo to run PPP on the serial port { write_settings # tell user the config has been changed $dialog --backtitle "$backtitle" --title "Configuration Changed" --msgbox \ "The network configuration has been changed.\nPPP on the serial port is now ENABLED\nand bash on the serial port is DISABLED. PPP will run at 57600 bps." 10 60 } ############################## # modem_conf() { # tell the user that modem dialups are not supported $dialog --yesno "Using the internal modem is subject to the Alt DUN Service being in operation. If you choose this option, and it doesn't work, then you will need to buy a network card.\n\nAre you sure that you want to use the internal modem?" 12 60 # user bailed out if [ "$?" -ne "0" ]; then return; fi # ask for the phone number get_phone if [ ! -z "$abort" ]; then return; fi # ask for the username get_username if [ ! -z "$abort" ]; then return; fi # ask for the password (hide the password as it's entered? do we care?) # don't care -ed get_password if [ ! -z "$abort" ]; then return; fi # write the new config for tclient echo "$dialconfig:$phone:127.0.0.1:8000:$username:$password:" \ > $tclient || fatal "Cannot write to $tclient" # wallop the chap/pap secrets files with the currently entered password echo -e "*\t*\t$password" > $chapsec || fatal "Cannot write to $chapsec" echo -e "*\t*\t$password" > $papsec || fatal "Cannot write to $papsec" # replace the username in the ppp-options file if [ -n "`grep ^user $pppops`" ]; then # change setting cat $pppops | sed "s/^user.*/user $username/" > $pppops.tmp || \ fatal "Cannot update $pppops" mv -f $pppops.tmp $pppops else echo "user $username" >> $pppops || fatal "Cannot append to $pppops" fi # change the config in the settings file write_settings # display the new config file $dialog --backtitle "$backtitle" --title "Configuration Changed" --msgbox \ "The dialup configuration has been changed.\nThe following screen will show the new configuration.\nVerify it is correct.\n(Use the left/right arrows to scroll)" 10 60 $dialog --backtitle "$backtitle" --title "tclient.conf" --textbox $tclient 10 60 } ############################## # # Display form to get IP address for NIC. No default, ie DHCP mode get_ip() { defip=$ip if [ "$defip" == "DHCP" ]; then defip=""; fi $dialog --backtitle "$backtitle" --title "IP Address/DHCP" --nocancel \ --inputbox "Enter IP Address.\nLeave null for DHCP." 10 40 $defip \ 2> /tmp/ipaddress.$$ if [ "$?" == "0" ]; then ip=`cat /tmp/ipaddress.$$` rm /tmp/ipaddress.$$ if [ -z "$ip" ]; then # no IP entered, DHCP mode, display message ip="DHCP" $dialog --backtitle "$backtitle" --title "DHCP" --msgbox \ "By not entering an IP address, you have set DHCP mode active." 10 60 else # static ip entered, display message $dialog --backtitle "$backtitle" --title "Static IP" --msgbox \ "By entering an IP address, you have set static IP mode." 10 60 fi else abort="yes" fi } ############################## # # Asks the user for the MAC address to use, or construct a random one # get_mac() { # user did aborted entering an IP if [ ! -z "$abort" ]; then return; fi $dialog --backtitle "$backtitle" --title "MAC Address" --nocancel \ --inputbox "Enter the full MAC Address to use.\nYou must change this if you are running multiple TiVos." 10 50 $mac 2>/tmp/macaddress.$$ if [ "$?" == "0" ]; then mac=`cat /tmp/macaddress.$$` rm /tmp/macaddress.$$ if [ -z "$mac" ]; then # no MAC entered, ask user again get_mac fi else abort="yes" fi } ################################### # Get timing for the turbonet card get_timing() { if [ ! -z "$abort" ]; then return; fi $dialog --clear --backtitle "$backtitle" --title "Turbonet Timing Value" \ --menu "Enter the timing parameter you would like.\n\n[Up][Down] to move\n[Enter] to select option." \ 10 60 0 \ "3" "Optimal timing" \ "4" "Normal timing" \ "16" "Failsafe timing" \ 2> /tmp/timing.$$ if [ "$?" == "0" ]; then timing=`cat /tmp/timing.$$` rm /tmp/timing.$$ if [ -z "$timing" ]; then # no value entered, ask again get_timing fi else abort="yes" fi } ############################## # # Asks the user for the subnet mask to use, 255.255.255.0 (class C) is default get_netmask() { # user did aborted entering an IP or MAC if [ ! -z "$abort" ]; then return; fi defmask=$netmask if [ -z "$defaultmask" ]; then defmask="255.255.255.0"; fi $dialog --backtitle "$backtitle" --title "Subnet Mask" --nocancel --inputbox \ "Enter subnet mask to use." 10 40 $defmask 2>/tmp/netmask.$$ if [ "$?" == "0" ]; then netmask=`cat /tmp/netmask.$$` rm /tmp/netmask.$$ if [ -z "$netmask" ]; then # no subnet mask entered, ask the user again get_netmask fi else abort="yes" fi } ############################## # # Asks the user for the gateway ip/default route to use, 192.168.1.249 is default get_gateway() { # user did aborted entering an IP or MAC or mask if [ ! -z "$abort" ]; then return; fi defgateway=$gateway if [ -z "$defgateway" ]; then defgateway="192.168.1.249"; fi $dialog --backtitle "$backtitle" --title "Gateway IP" --nocancel --inputbox \ "Enter gateway IP address / default route to use." 10 40 $defgateway \ 2>/tmp/gateway.$$ if [ "$?" == "0" ]; then gateway=`cat /tmp/gateway.$$` rm /tmp/gateway.$$ if [ -z "$gateway" ]; then # no gateway / default route entered, ask the user again get_gateway fi if [ "$gateway" = "$ip" ]; then $dialog --msgbox "The IP address of your default gateway has to be different to the IP address that you gave to your router, $ip. Please re-enter the gateway address." 8 60 get_gateway fi else abort="yes" fi } ############################## # # User is in DHCP mode, ask them for the hostname to send to the DHCP server. # If it supports DNS, oztivo is default get_hostname() { # user did aborted entering an IP or MAC or mask or gateway if [ ! -z "$abort" ]; then return; fi defhostname=$hostname if [ -z "$defhostname" ]; then defhostname="altepgtivo"; fi $dialog --backtitle "$backtitle" --title "DHCP Hostname" --nocancel \ --inputbox "Enter DHCP hostname to use.\nNot all DHCP servers support this\n(they will just ignore it).\nModify this if you have multiple TiVos." \ 12 50 $defhostname 2>/tmp/hostname.$$ if [ "$?" == "0" ]; then hostname=`cat /tmp/hostname.$$` rm /tmp/hostname.$$ if [ -z "$hostname" ]; then # no hostname entered, ask again get_hostname fi else abort="yes" fi } ############################## # # Display form to get SSID to connect to get_SSID() { # user aborted entering an IP if [ ! -z "$abort" ]; then return; fi defSSID=$ssid if [ -z "$defSSID" ]; then defSSID="default"; fi $dialog --backtitle "$backtitle" --title "SSID" --nocancel --inputbox \ "Enter the SSID to connect to." 10 40 $defSSID 2>/tmp/ssid.$$ if [ "$?" == "0" ]; then ssid=`cat /tmp/ssid.$$` rm /tmp/ssid.$$ if [ -z "$ssid" ]; then # no SSID entered, ask again. get_SSID fi else abort="yes" fi } ############################## # # Display form to get encryption level settings get_WEP() { # user aborted entering an IP if [ ! -z "$abort" ]; then return; fi $dialog --backtitle "$backtitle" --title "WEP Encryption" --nocancel \ --menu "Select WEP Encyption level." 10 40 0 \ "None" "No Encryption" \ "64" "64 Bit Encyption" \ "128" "128 Bit Encyption" 2>/tmp/wep.$$ if [ "$?" == "0" ]; then wep=`cat /tmp/wep.$$` rm /tmp/wep.$$ if [ "$wep" != "None" ]; then get_wepkey fi else abort="yes" fi } ############################## # # User has selected 64/128 bit encryption, need to get key get_wepkey() { $dialog --backtitle "$backtitle" --title "WEP Key" --nocancel \ --inputbox "Enter the $wep bit WEP key." 10 60 $WEPkey 2>/tmp/WEPkey.$$ if [ "$?" == "0" ]; then wepkey=`cat /tmp/WEPkey.$$` rm /tmp/WEPkey.$$ keylength=`echo $wepkey |wc -L |awk '{ print $1 }'` if [ "$wep" == "64" ]; then if [ "$keylength" -lt "10" ]; then # too short, display error $dialog --backtitle "$backtitle" --title "Error" --msgbox \ "The WEP key entered was too short.\n64 bit keys must be 10 characters long.\nPlease check it." 10 60 # ask again get_wepkey elif [ "keylength" -gt "10" ]; then # too long, display error $dialog --backtitle "$backtitle" --title "Error" --msgbox \ "The WEP key entered was too long.\n64 bit keys must be 10 characters long.\nPlease check it." 10 60 # ask again get_wepkey fi elif [ "$wep" == "128" ]; then if [ "$keylength" -lt "26" ]; then # too short, display error $dialog --backtitle "$backtitle" --title "Error" --msgbox \ "The WEP key entered was too short.\n128 bit keys must be 26 characters long.\nPlease check it." 10 60 # ask again get_wepkey elif [ "keylength" -gt "26" ]; then # too long, display error $dialog --backtitle "$backtitle" --title "Error" --msgbox \ "The WEP key entered was too long.\n128 bit keys must be 26 characters long.\nPlease check it." 10 60 # ask again get_wepkey fi fi else abort="yes" fi } ############################## # # Get the ISP's phone number get_phone() { defphone=$phone $dialog --backtitle "$backtitle" --title "Dialup Number" --nocancel \ --inputbox "Enter ISP's Dialup number" 10 40 $defphone 2>/tmp/phone.$$ if [ "$?" == "0" ]; then phone=`cat /tmp/phone.$$` rm /tmp/phone.$$ # (if number too short/long.. too bad. User can learn to type.) if [ -z "$phone" ]; then # no phone number entered, ask again get_phone fi else abort="yes" fi } ############################## # # Get the user's ISP username get_username() { defusername=`grep ^username= $settings| cut -f 2 -d "="` $dialog --backtitle "$backtitle" --title "Dialup Username" --nocancel --inputbox "Enter the username required to connect to your ISP" 10 40 $defusername 2>/tmp/username if [ "$?" == "0" ]; then username=`cat /tmp/username` rm /tmp/username if [ -z "$username" ]; then # no username entered. I've never heard of an ISP not requiring a username (HTF would that work?). Ask again.. get_username fi else abort="yes" fi } ############################## # get_password() # get the user's ISP password { defpassword=$password $dialog --backtitle "$backtitle" --title "Dialup Password" --nocancel \ --inputbox "Enter the password required to connect to your ISP" 10 40 \ $defpassword 2>/tmp/password.$$ if [ "$?" == "0" ]; then password=`cat /tmp/password.$$` rm /tmp/password.$$ if [ -z "$password" ]; then # No password entered. I've never heard of an ISP not requiring a # password. Ask again.. get_password fi else abort="yes" fi } ############################## # build_net_conf() # builds the oztivo.conf file based on the user's input { # get all the necessary settings from the user to setup an appropriate nic: # Static IP/DHCP # MAC address # Subnet Mask (static IP) # Default Route (static IP) # hostname (DHCP) # SSID (airnet) # Encryption (level/key) (airnet) # get IP address first/DHCP mode get_ip if [ "$nic" == "TurboNet" -o "$nic" == "Cachecard" ]; then # get MAC address get_mac fi if [ "$nic" == "TurboNet" ]; then # get timing get_timing fi if [ "$ip" != "DHCP" ]; then # user set a static IP # get subnet mask get_netmask # get gateway/default route get_gateway else # DHCP mode # get DHCP hostname get_hostname netmask="" gateway="" fi if [ "$nic" == "AirNet" ]; then # get the SSID to connect to get_SSID # get encryption settings get_WEP else ssid="" wep="" wepkey="" fi # Save the file write_settings } ############################## # # Ask user what guide data emulator to use emu_conf() { # ask the user for emu address get_emu # user aborted selecting/entering emulator address if [ ! -z "$abort" ]; then return; fi if [ "$emulator" == "194.1.151.205" ]; then # must be running on port 80 emulatorport="80" else # get the port to use get_emu_port fi # Save the file write_settings } ############################## # # Ask user to select what guide data emulator to use get_emu() { # ask what emulator to use $dialog --backtitle "$backtitle" --title "Select emulator" --menu \ "[Up][Down] to move\n[Enter] to select" 10 60 0 \ "194.1.151.205" "Use 194.1.151.205, the UK emulator" \ "www.oztivo.net" "Use www.oztivo.net, the OZ emulator" \ "hydra.demon.nl" "Use hydra.demon.nl, The Netherlands emulator" \ "other" "Enter emulator IP/address manually" 2>/tmp/emulator.$$ # add more emulators above other if [ "$?" == "0" ]; then # user did not cancel emulator=`cat /tmp/emulator.$$` rm -f /tmp/emulator.$$ # work out what to do if [ "$emulator" == "other" ]; then # ask the user to enter the ip/address get_other_emu fi else abort="yes" fi } ############################## # # Ask user to enter what guide data emulator to use get_other_emu() { defemu=$emulator $dialog --backtitle "$backtitle" --title "Emulator IP/Address" --nocancel \ --inputbox "Enter Emulator IP or Address." 10 40 $defemu 2>/tmp/emuaddress.$$ if [ "$?" == "0" ]; then emulator=`cat /tmp/emuaddress.$$` rm -f /tmp/emuaddress.$$ if [ -z "$emulator" ]; then # no address entered, error, ask again get_other_emu fi else abort="yes" fi } ############################## # # Ask user to enter the guide data emulator port get_emu_port() { defport=$emulatorport $dialog --backtitle "$backtitle" --title "Emulator Port" --nocancel \ --inputbox "Enter Emulator Port.\nMost are 80 or 8000" 10 40 \ $defport 2>/tmp/emuport.$$ if [ "$?" == "0" ]; then emulatorport=`cat /tmp/emuport.$$` rm -f /tmp/emuport.$$ if [ -z "$emulatorport" ]; then # no port entered, error, ask again get_emu_port fi else abort="yes" fi } # # Perform network configuration on the $settings file net_conf() { # display menu for user to choose NIC $dialog --clear --backtitle "$backtitle" --title "Select NIC to Install" \ --menu "[Up][Down] to move\n[Enter] to select option" 10 60 0 \ "Auto" "Auto-sense the NIC" \ "TurboNet" "100Mbit Wired NIC" \ "Cachecard" "100Mbit Wired NIC + Optional RAM" \ "AirNet" "11Mbit Wireless NIC" \ "TiVoNet" "10Mbit Wired NIC (ISA Card) (not common)" \ "PPPonDSS" "PPP on the Serial Port" \ "Modem" "Dialup using built in modem" \ "Emulator" "Select the guide server to use" \ "View" "Display Current Configuration File" \ "Exit" "Exit Network Configuration" 2>/tmp/nic2install.$$ if [ "$?" == "0" ]; then # user did not cancel cmd=`cat /tmp/nic2install.$$` rm -f /tmp/nic2install.$$ case $cmd in View) view_net_conf # show the network menu again net_conf ;; Auto) nic=$cmd build_net_conf cachecard_warning ;; TurboNet) nic=$cmd build_net_conf cachecard_warning ;; Cachecard) nic=$cmd build_net_conf cachecard_warning ;; AirNet) nic=$cmd build_net_conf cachecard_warning ;; TiVoNet) nic=$cmd build_net_conf cachecard_warning ;; PPPonDSS) nic=$cmd pppondss_conf cachecard_warning ;; Modem) nic=$cmd modem_conf cachecard_warning ;; Emulator) emu_conf ;; Exit) disable_device; $dialog --clear; stty sane; exit 0 ;; esac else disable_device; $dialog --clear; stty sane; exit 0 fi } ############################## # MAIN PROGRAM ############################## # Make a random MAC address random_macaddr # Get any device named as $1 if [ $# = 1 ]; then # Check that we are running on the CD if [ ! -d /cdrom/KNOPPIX ]; then fatal "This program is not running on the CD, so you cannot supply the $1 argument." fi device=$1 settings="$mountpoint/etc/oztivo.conf" dhclient="$mountpoint/etc/dhclient.conf" tclient="$mountpoint/etc/tclient.conf" chapsec="$mountpoint/etc/chap-secrets" papsec="$mountpoint/etc/pap-secrets" pppops="$mountpoint/etc/ppp-options" dialog="/usr/bin/dialog" else # Check that we are not running on the CD if [ -d /cdrom/KNOPPIX ]; then dialog="/usr/bin/dialog" fatal "This program is running on the CD, you must supply the name of the device where the Linux partition was created, e.g. $0 hda" fi fi # Make the device read/write enable_device # Create a default file if it doesn't exist if [ ! -f $settings -o ! -s $settings ]; then write_settings; fi updated="" # Load the existing values, give the main menu source $settings while true; do abort=""; net_conf; done disable_device $dialog --clear; stty sane exit 0