diff options
author | Benedikt Boehm <hollow@gentoo.org> | 2005-10-09 08:31:20 +0000 |
---|---|---|
committer | Benedikt Boehm <hollow@gentoo.org> | 2005-10-09 08:31:20 +0000 |
commit | 53c0ee2f8b484270b6ad60d53c5f7247e9a428db (patch) | |
tree | 693a49c846b08b89cc2c784dc692dd44904ed2ec | |
parent | Refreshing baselayout-vserver with revision 1560 from baselayout. (diff) | |
download | baselayout-vserver-53c0ee2f8b484270b6ad60d53c5f7247e9a428db.tar.gz baselayout-vserver-53c0ee2f8b484270b6ad60d53c5f7247e9a428db.tar.bz2 baselayout-vserver-53c0ee2f8b484270b6ad60d53c5f7247e9a428db.zip |
add back net services
svn path=/baselayout-vserver/trunk/; revision=52
47 files changed, 8486 insertions, 408 deletions
@@ -9,7 +9,7 @@ # IPv4 and IPv6 localhost aliases 127.0.0.1 localhost -::1 localhost +::1 localhost # # Imaginary network. diff --git a/init.d/bootmisc b/init.d/bootmisc index ee12ca6..f9a76b3 100755 --- a/init.d/bootmisc +++ b/init.d/bootmisc @@ -34,6 +34,12 @@ start() { # Take care of random stuff [ /var/lock | /var/run | pam ] # + if [[ -d /var/lib/net-scripts/state ]] ; then + ebegin "Cleaning /var/lib/net-scripts/state" + rm -rf /var/lib/net-scripts/state/* + eend 0 + fi + ebegin "Cleaning /var/lock, /var/run" rm -rf /var/run/console.lock /var/run/console/* @@ -94,6 +100,13 @@ start() { eend 0 fi + ( + # Make sure our X11 stuff have the correct permissions + mkdir -p /tmp/.{ICE,X11}-unix + chown 0:0 /tmp/.{ICE,X11}-unix + chmod 1777 /tmp/.{ICE,X11}-unix + [[ -x /sbin/restorecon ]] && restorecon /tmp/.{ICE,X11}-unix + ) &> /dev/null fi # diff --git a/init.d/net b/init.d/net deleted file mode 120000 index 2995a4d..0000000 --- a/init.d/net +++ /dev/null @@ -1 +0,0 @@ -dummy
\ No newline at end of file diff --git a/man/MAKEDEV.8 b/man/MAKEDEV.8 index b3c9b84..c18c42c 100644 --- a/man/MAKEDEV.8 +++ b/man/MAKEDEV.8 @@ -1,30 +1,26 @@ -.\" $Id: MAKEDEV.8 334 2003-03-09 09:06:23Z azarah $ -.TH MAKEDEV 8 "14th August 1994" Linux "Linux Programmer's Manual" +.\" $Id: MAKEDEV.8 1421 2005-08-23 23:56:23Z vapier $ +.TH MAKEDEV 8 "May 17 2002" Linux "Make Linux Devices" .SH NAME MAKEDEV \- create devices .SH SYNOPSIS -.B "cd dev; ./MAKEDEV -V" +.B "cd /dev; ./MAKEDEV [ -n ] [ -v ] [ update ]" .br -.B "cd dev; ./MAKEDEV [ -n ] [ -v ] update" +.B "cd /dev; ./MAKEDEV [ -n ] [ -v ] [ generic ] [ local ] [ group-keyword ... device ... ]" .br -.BI "cd dev; ./MAKEDEV [ -n ] [ -v ] [ -d ]" " device ..." +.BI "cd /dev; ./MAKEDEV [ -n ] [ -v ] [ -d ]" " device ..." .SH DESCRIPTION .B MAKEDEV -is a script that will create the devices in \fC/dev\fP used to interface +is a script that will create the devices in +.B /dev +used to interface with drivers in the kernel. .PP -This man page is woefully out of date. A large number of devices are supported -that are not documented here. -.PP Note that programs giving the error ``ENOENT: No such file or directory'' normally means that the device file is missing, whereas ``ENODEV: No such device'' normally means the kernel does not have the driver configured or loaded. .SH OPTIONS .TP -.B \-V -Print out version (actually RCS version information) and exit. -.TP .B \-n Do not actually update the devices, just print the actions that would be performed. @@ -46,9 +42,7 @@ to reflect your site's settings. Near the top of the file is a mapping from device type to user, group and permissions (e.g. all CD-ROM devices are set from the \fC$cdrom\fP variable). If you wish to change the defaults, this is the section to edit. -.SH DEVICES -.TP -.B General Options +.SH GENERAL OPTIONS .TP .B update This only works on kernels which have \fC/proc/interrupts\fP (introduced @@ -59,94 +53,246 @@ Devices which are new since then or have a different major number are created, and those which are no longer configured are deleted. .TP .B generic -Create a generic subset of devices. This is the standard devices, plus -floppy drives, various hard drives, pseudo-terminals, console devices, -basic serial devices, busmice, and printer ports. -.TP -.B -std -Standard devices. -These are: +Create a generic subset of devices. This subset consists of the +standard devices, plus floppy drives, various hard drives, CD-ROM +drives, pseudo-terminals, console devices, basic serial devices, +busmice, audio devices, video framebuffers, printer ports, and some +specialized devices. The generic subset varies somewhat according to +architecture; see the +.B /dev/MAKEDEV +script itself for details. +.TP +.B local +This simply runs +.BR MAKEDEV.local . +This is a script that can create any local devices. +.SH DEVICE GROUPS +.B MAKEDEV +creates groups of devices when passed keywords for the group. +Each listing below shows the +.B MAKEDEV +keyword and then lists the devices which will be created. Many +devices can also be specified individually. +.SH STANDARD DEVICES +.TP +.B std +Creates this group of standard devices: .B mem -\- acess to physical memory; +for access to physical memory, .B kmem -\- access to kernel virtual memory; +for access to kernel virtual memory, .B null -\- null device (infinite sink); +the null device (infinite sink), .B port -\- access to I/O ports; +for access to I/O ports, .B zero -\- null byte source (infinite source); -.B core -\- symlink to /proc/kcore (for kernel debugging); +the null byte source (infinite source), +.BR core , +a symlink to /proc/kcore (for kernel debugging), .B full -\- always returns ENOSPACE on write; -.B ram -\- ramdisk; +which always returns ENOSPACE on write, +.BR random " and " urandom +random byte generators, and .B tty -\- to access the controlling tty of a process. +to access the controlling tty of a process. The +loopback disk devices +.B loop0 +through +.BR loop7 +are also created in the +.B std +group. These allow you to use a regular file as a +block device. A filesystem image can be mounted, +and used as though it were a filesystem on a partition or other +block device. +.B loop +may also be used as a separate keyword to create the 8 loop devices. Finally, the +.B ram +group of memory devices is also created by the +.B std +keyword (see below). +.SH MEMORY DEVICES +.TP +.B ram +This is the keyword used to generate the ramdisk devices +.BI ram {0..16} +and the +.B ram +symlink. This group does not include +.BR initrd . +.TP +.B initrd +Ramdisk which has been pre-initialized by a bootloader. +.B initrd +is not created in the +.B ram +group; it must be specifically included +in the command line if you want it to be created. +.TP +.IR cpu " or " microcode +Creates the CPU microcode update interface in the +.B cpu/ +folder, with devices +.BR microcode , +and subfolders +.BR {0..3} +each containing devices +.BR msr " and " cpuid . +.TP +.B rom +Creates the +.BI rom {0..7} " rrom" {0..7} " flaxh" {0..7} +and +.BI rflash {0..7} +flash memory card devices. +.BR rrom " and " rflash +devices are read-only. +.SH CONSOLE DEVICES +.TP +.B console +This keyword creates virtual consoles; +.BI tty {0..63} +devices, the corresponding +.B vcs +and +.B vcsa +devices which are used to generate screen-dumps, and the +.B console +device itself plus appropriate symlinks. +To create the console device alone, use +.BR consoleonly . +The device +.B tty0 +is the currently active virtual console. The +.B console +device serves the same function. +.SH PSEUDO TERMINALS .TP -.B local -This simply runs -.BR MAKEDEV.local . -This is a script that can create any local devices. +.B pty +This keyword creates the Pseudo-TTY masters +.BI pty {a..e,p..z} +and corresponding +.BI tty {a..e,p..z} +devices, along with +.BR ptmx . +Each possible argument will create a bank of 16 master and slave pairs. +The master pseudo-terminals are +.BR pty{p..s}{0..9a..f} , +and the slaves are +.BR tty{p..s}{0..9a..f} . +.SH SERIAL DEVICES .TP -.B Virtual Terminals +.I ttyS{0..63} +Standard serial ports. There is no group keyword, you must +specify these individually. However +.BI ttyS{0..3} +are created under the +.B generic +option for most architectures. .TP -.I console -This creates the devices associated with the console. This is the virtual -terminals -.RI tty x , -where -.I x -can be from 0 though 63. The device tty0 is the currently active vt, and -is also known as \fCconsole\fP. For each vt, there are two devices -.RI vcs x +.BR cyclades " or " ttyC +Creates Cyclades ports +.BI ttyC {0..31} \fR. +.TP +.BR digi " or " ttyD +Creates Digiboard serial card ports +.BI ttyD {0..15} \fR. +.TP +.BR stallion " or " ttyE +Creates Stallion devices +.BI ttyE {0..255} +and +.BI staliomem {0..3} \fR. +.TP +.BR computone " or " ttyF +Creates CompuTone serial card ports +.BI ttyH {0..255} +and special devices +.B ip2ipl{0,4,8,12} and -.RI vcsa x , -which are used to generate screen-dumps of the vt (the -.BI vcs x -is just the text, +.BR ip2stat{1,5,9,13} \fR. +.TP +.BR chase " or " ttyH +Creates Chase serial card ports +.BI ttyH {0..15} \fR. +.TP +.BR isdnmodem " or " ttyI +Creates isdn4linux virtual modem ports +.BI ttyI {0..63} \fR. +.TP +.BR isdn-tty +Also creates isdn4linux virtual modem ports +.BI ttyI {0..7} \fR. +.TP +.B isdnbri +Creates ISDN BRI driver devices +.B isdn{0..63} isdnctrl{0..63} ippp{0..63} and -.BI vcsa x -includes the attributes). +.BR isdninfo . .TP -.B Serial Devices +.B isdn-io +Also creates ISDN BRI driver devices +.B isdn{0..7} isdnctrl{0..7} ippp{0..7} +and +.BR isdninfo . +The +.B isdn-ippp +keyword can be used separately to create only the +.BI ippp {0..7} +devices. .TP -.I ttyS{0..63} -Serial ports and corresponding dialout device. For device -.BI ttyS x , -there is also the device -.BI cua x -which is used to dial out with. This can avoid the need for cooperative -locks in simple situations. -.TP -.I cyclades -Dial-in and dial-out devices for the cyclades intelligent I/O serial card. -The dial in device is -.BI ttyC x -and the corresponding dial-out device is -.BI cub x -Devices for 32 lines are created. -.TP -.B Pseudo Terminals -.TP -.I pty[p-s] -Each possible argument will create a bank of 16 master and slave -pairs. The current kernel (1.2) is limited to 64 such pairs. -The master pseudo-terminals are -.BR pty[p-s][0-9a-f] , -and the slaves are -.BR tty[p-s][0-9a-f] . +.B ppp +Creates a device independent PPP interface. +.TP +.B dcbri +Creates Spellcaster DataComm/BRI ISDN card devices +.BR dcbri{0..3} . +.TP +.BR riscom " or " ttyL +Creates Riscom serial card ports +.BI ttyL {0..15} \fR. +.TP +.BR PAM " or " ttyM +Creates PAM multimodem (or ISI serial card) ports +.BI ttyM {0..15} \fR. +.TP +.BR ESP " or " ttyP +Creates ESP ports +.BI ttyP {0..4} \fR. +.TP +.BR rocketport " or " ttyR +Creates Rocketport devices +.BI ttyR {0..63} \fR. +.TP +.BR ttyV +Creates Comtrol VS-1000 serial controller ports +.BI ttyV {0..15} \fR. .TP -.B Parallel Ports +.BR specialixIO8 " or " ttyW +Creates Specialix IO8+ ports +.BI ttyW {0..15} \fR. .TP -.I lp -Standard parallel ports. The devices are created +.BR specialix " or " ttyX +Creates Specialix ports +.BI ttyX {0..15} \fR. +.TP +.BI i2c +Creates +.BI i2c {0..7} +devices for the I2C bus interface. +.TP +.BI tlk +Philips SAA5249 Teletext signal decoder {2.6} ports +.BI tlk {0..3} \fR. +.SH PARALLEL PORTS +.TP +.IR lp +Creates the standard parallel ports .BR lp0 , .BR lp1 , and -.BR lp2 . +.BR lp2 +normally used for printers. These correspond to ports at 0x3bc, 0x378 and 0x278. Hence, on some machines, the first printer port may actually be .BR lp1 . @@ -154,27 +300,128 @@ Hence, on some machines, the first printer port may actually be .I par Alternative to .IR lp . -Ports are named -.BI par x +The same ports are created, but are named +.BI par {0..2} instead of -.BI lp x . +.BI lp {0..2} \fR. +.TP +.I parport +Creates raw parallel ports +.BR parport0 , +.BR parport1 , +and +.BR parport2 . +.TP +.B slm +Creates the Atari SLM ACSI laser printer (68k/Atari) ports +.BI slm {0..3} \fR. .TP -.B Bus Mice +.B pg +Parallel port generic ATAPI interface (devices +.BI pg {0..3} \fR. +.TP +.B paride +Parallel port IDE disk devices +.BI pd {a..d} +with 15 partitions on each. Also creates +.BR pcd{0..3} " and " pf{0..3} . +.SH OTHER BUS PORTS +.TP +.BR netlink " or " tap +Creates NetLink devices +.B route skip fwmonitor +and +.BI tap {0..15} +Ethertap devices. +The +.BI tap x +virtual ethernet device was designed as low level kernel support for +Ethernet tunneling. Userland application can write Ethernet frame to +.BI /dev/tapX +and the kernel will receive this frame from tapX interface. +Every frame the kernel writes to a +.BI tapX +interface can be read by a userland application from the corresponding +.BI /dev/tapX +device. +.TP +.B enskip +ENskip kernel encryption package. +.TP +.B qng +ComScire Quantum Noise Generator. +.TP +.B ipsec +The Free S/WAN implementation of IPSEC. +.TP +.B adb +On powerpc, creates +.B adb +for the Apple Data Bus and +.BR adbmouse . +On m68k, +.B adb +creates the ACSI disk device +.B adb +and partitions +.B adb1 +through +.BR adb15 . +.TP +.B hamradio +Creates the +.BI scc {0..7} +and +.BI bc {0..3} +device groups. +.TP +.B comx +Creates COMX devices +.BI comx {0..4} \fR. +.TP +.B irda +Creates IrCOMM devices (IrDA serial/parallel emulation) +.B ircomm0 ircomm1 irlpt0 +and +.BR irlpt1 . +.TP +.B comedi +Control and Measurement devices +.BI comedi {0..3} \fR. +.SH MOUSE DEVICES .TP .I busmice -The various bus mice devices. This creates the following devices: -.B logimouse +This keyword creates the following devices: +.B logibm (Logitech bus mouse), -.B psmouse +.B psaux (PS/2-style mouse), -.B msmouse +.B inportbm (Microsoft Inport bus mouse) and -.B atimouse +.B atibm (ATI XL bus mouse) and -.B jmouse +.B jbm (J-mouse). .TP -.B Joystick Devices +.I m68k-mice +Creates mouse devices for the m68k architecture, including: +.BR amigamouse , +.BR amigamouse1 , +.B atarimouse +and +.BR adbmouse . +.TP +.I input +On powerpc, this keyword creates the +.I input +folder which groups input devices +.BR mice , +.BI mouse {0..3} \fR, +.BI event {0..3} \fR, +and +.BI js {0..3} +(joystick), and creates these devices inside. +.SH JOYSTICK DEVICES .TP .I js Joystick. Creates @@ -182,28 +429,61 @@ Joystick. Creates and .BR js1 . .TP -.B Disk Devices +.I djs +Digital joystick. Creates +.B djs0 +and +.BR djs1 . +.SH USB DEVICES .TP -.I fd[0-7] +.B usb +USB is a general purpose I/O bus which can serve many purposes. The +.B usb +keyword creates a +.B usb +folder, and devices in the folder: +.BI lp {0..15} +(printer), +.BI mouse {0..15} +(USB connected mice), +.BI ez {0..15} +(firmware loaders) +.BI scanner {0..15} +(scanner interfaces), +.BI ttyACM {0..15} +and +.BI ttyUSB {0..15} +(dialout devices), +and +.B rio500 +the Diamond Rio 500 device. +.SH DISK DEVICES +.TP +.BI fd {0..7} Floppy disk devices. The device .BI fd x -is the device which autodetects the format, and the additional devices are +is the device which autodetects the format, +and the additional devices are fixed format (whose size is indicated in the name). The other devices are named as -.BI fd xLn . -The single letter -.I L -identifies the type of floppy disk (d = 5.25" DD, h = 5.25" HD, D = 3.5" -DD, H = 3.5" HD, E = 3.5" ED). The number +.BI fd x{dqhu}n . +The single letter +.RI ( d , +.IR q , +.IR h or +.IR u ) +signifies the type of drive: 5.25" Double Density (d), +5.25" Quad Density (q), 5.25" High Density (h) or 3.5" +(any model, u). The number .I n -represents the capacity of that format in K. Thus the standard formats -are +represents the capacity of that format in K. +Thus the standard formats are .BI fd x d360 , .BI fd x h1200 , -.BI fd x D720 , -.BI fd x H1440 , +.BI fd x 720 , +.BI fd x 1440 , and -.RI fd x E2880 . +.BI fd x 2880 . .IP For more information see Alain Knaff's fdutils package. .IP @@ -217,12 +497,16 @@ through .BI fd7 * are floppy disks on the second controller. .TP -.I hd[a-d] -AT hard disks. The device +.BI fd {0..7} -bare +Creates just the autodetecting floppy device specified, without the fixed +format devices. +.TP +.BI hd {a..l} +AT (ide) hard disks. The device .BI hd x provides access to the whole disk, with the partitions being -.BI hd x [0-20]. -The four primary partitions are +.BI hd x {1..63}. +For i386, the four primary partitions are .BI hd x 1 through .BI hd x 4, @@ -230,95 +514,237 @@ with the logical partitions being numbered from .BI hd x 5 though .BI hd x 20. -(A primary partition can be made into an extended partition, which can hold -4 logical partitions). -By default, only the devices for 4 logical partitions are made. The -others can be made by uncommenting them. +(A primary partition can be made into an extended partition, which can +hold 4 logical partitions). Other architectures may not differentiate +partition types. By default, devices for 20 logical partitions are +made. The kernel supports up to 63 partitions per device. .IP -Drives hda and hdb are the two on the first controller. If using the new -IDE driver (rather than the old HD driver), then hdc and hdd are the two +Drives +.B hda +and +.B hdb +are the two on the primary controller +.B hdc +and +.B hdd +are the two drives on the secondary controller. These devices can also be used to -acess IDE CDROMs if using the new IDE driver. +access IDE CDROMs. Additional devices +.BI hd {e..l} +can be created. .TP -.I xd[a-d] -XT hard disks. Partitions are the same as IDE disks. +.BI xd {a..d} +XT hard disks. Partitions are the same as IDE disks, except only 8 +partitions are created. .TP -.I sd[a-h] +.BI sd {a..h} SCSI hard disks. The partitions are similar to the IDE disks, but there is a limit of 11 logical partitions -.RI (sd x 5 +.BI sd x 5 through -.RI sd x 15). -This is to allow there to be 8 SCSI disks. +.BI sd x 15, +to allow there to be 8 SCSI disks on a system +(addresses 0 through 7). +.TP +.BI sd {i..z} +and +.BI sd {a..d}{a..z} +The kernel (and MAKEDEV) can handle up to 128 SCSI disks (up to +.BR sddx ). +15 partition devices are created for each. .TP -.I loop -Loopback disk devices. These allow you to use a regular file as a -block device. This means that images of filesystems can be mounted, -and used as normal. This creates 8 devices loop0 through loop7. +.B eda edb +MCA ESDI hard disk. Partitions are handled the same as hd. .TP -.B Tape Devices +.BI dasd {a..z} +Direct Access Storage Devices for the s390 architecture. Currently +only one device partition is created (for example, +.BR dasda1 ). +.TP +.BI ada {a..p} +ACSI disk (68k/Atari). 15 partitions are created for each. +.TP +.BI dac960. {0..7} +Mylex DAC960 PCI RAID controller. For this device, an +.B rd +directory is created. 32 logical devices +.BI c x d {0..31} +are created for each unit +.I x +specified, each with 7 partitions +.BI c x d {0..31} p {1..7} \fR. +The +.B dac960 +keyword will create all 7 units at once. .TP -.I st[0-7] -SCSI tapes. This creates the rewinding tape device +.BI dpti +Adaptec I2O RAID and DPT SmartRAID V I2O controllers. Creates +7 devices for handling up to 7 controllers. +.TP +.BI ataraid. {0..7} +Obsolete, device not in current devices.txt. For this device, an +.B ataraid +directory is created. +.BI d x +is created for each unit +.I x +specified, and 15 partitions +.BI d x p {1..15} \fR. +The +.B ataraid +keyword will create all 7 units at once. +.TP +.BI i2o.hd{a..d}{a..z} +I2O based harddisk drives. Device nodes are located in the +.B i2o +directory. The filename is followed by a number that specifies the partition on +each disk. The numbers are handled the same as hd. +.TP +.BI ida. {0..7} +Compaq Intelligent Drive Array. For this device, an +.B ida +directory is created. 16 logical devices +.BI c x d {0..15} +are created for each unit +.I x +specified, each with 15 partitions +.BI c x d {0..15} p {1..15} \fR. +The +.B ida +keyword will create the first three units. +.TP +.BI cciss. {0..7} +Compaq Next Generation Drive Array. For this device, a +.B cciss +directory is created. 16 logical devices +.BI c x d {0..15} +are created for each unit +.I x +specified, each with 15 partitions +.BI c x d {0..15} p {1..15} \fR. +The +.B cciss +keyword will create the first three units. +.TP +.BI md +Creates Metadisk (RAID) disk array with 16 devices. +.SH TAPE DEVICES +.TP +.I st{0..7} +SCSI tape devices. This creates the rewinding tape device .BI st x and the non-rewinding tape device -.BI nst x . +.BI nst x , +for each of modes 0 through 3. .TP .I qic -QIC-80 tapes. The devices created are +QIC-11, -24, -120, and -150 tapes. The devices created are +.B ntpqic11 tpqic11 ntpqic24 tpqic24 ntpqic120 tpqic120 ntpqic150 +and +.B tpqic150 +tape devices, along with .BR rmt8 , .BR rmt16 , .BR tape-d , and .BR tape-reset . .TP -.I ftape +.I ftape Floppy driver tapes (QIC-117). There are 4 methods of access depending on the floppy tape drive. For each of access methods 0, 1, 2 and 3, the devices -.BI rft x +.BI qft x +.BI zqft x +and +.BI rawqftx (rewinding) and -.BI nrft x -(non-rewinding) are created. For compatability, devices +.BI nqft x +.BI nzqft x +.BI nrawqdt x +(non-rewinding) are created. For compatibility, devices .B ftape and .B nftape are symlinks to -.B rft0 +.B qft0 and -.B nrft0 +.B nqft0 respectively. .TP -.B CDROM Devices +.B ht0 +Creates IDE tape devices +.B ht0 +and +.BR nht0 . +.TP +.BI pt {0..3} +Creates parallel port ATAPI tape devices +.B pt{0..3} +and +.BR npt{0..3} . +.SH CDROM DEVICES +.TP +.BR sr " or " scd " or " scd-all +Creates +.BI scd {0..16} +SCSI CD players and +.BI sr {0..16} +symlinks for these devices. +.B cdrom +is a symlink which can be created by the user to the active CD device. +It is not created by +.BR MAKEDEV . +.TP +.B pktcdvd +Provides packet writing devices +.BI pktcdvd {0..3} +for CD/DVD. +.TP +.I pcd{0..3} +Parallel port ATAPI CD-ROM devices .TP -.I scd[0-7] -SCSI CD players. +.I sonycd +Sony CDU-31a CD-ROM .TP -.I sonycd -Sony CDU-31A CD player. +.I mcd +Mitsumi CD-ROM .TP -.I mcd -Mitsumi CD player. +.I mcdx +Obsolete, device not in current devices.txt. .TP .I cdu535 -Sony CDU-535 CD player. +Sony CDU-535 CD-ROM +.TP +.IR lmscd +Philips LMS CM-205 CD-ROM. The newer name for this device is +.IR cm205 , +but MAKEDEV creates only lmscd at this time. +.TP +.I cm206cd +Philips LMS CM-206 CD-ROM +.TP +.I bpcd +MicroSolutions BackPack parallel port CD-ROM (Obsolete - use pcd) .TP -.I lmscd -LMS/Philips CD player. +.I sbpcd{0..15} +Matsushita (Panasonic/SoundBlaster) CD-ROM. Units {0..3} are created with the keyword +.BR sbpcd . .TP -.I sbpcd{,1,2,3} -Sound Blaster CD player. The kernel is capable of supporting 16 CDROMs, -each of which is accessed as -.BR sbpcd[0-9a-f] . -These are assigned in groups of 4 to each controller. -.B sbpcd -is a symlink to -.BR sbpcd0 . -.\" .TP -.\" .I idecd -.\" NEC CDR-260 (note: this will probably be obsoleted by the new IDE driver). +.I aztcd +Aztech/Orchid/Okano/Wearnes CD-ROM .TP -.B Scanner +.I gscd +GoldStar CD-ROM +.TP +.I optcd +Optics Storage CD-ROM +.TP +.I sjcd +Sanyo CD-ROM +.TP +.I hitcd +Hitachi CD-ROM +.SH SCANNERS .TP .I logiscan Logitech ScanMan32 & ScanMan 256. @@ -328,34 +754,105 @@ Mustek M105 Handscanner. .TP .I ac4096 A4Tek Color Handscanner. -.TP -.B Audio +.SH AUDIO DEVICES .TP .I audio This creates the audio devices used by the sound driver. These include -.BR mixer , -.BR sequencer , -.BR dsp , +.B mixer mixer{1..3} +(Mixer controls), +.B sequencer +(Audio sequencer), +.B dsp dsp{1..3} +(Digital audio), +.B sndstat +(Sound card status information), +.B audioctl +(SPARC audio control device) +and +.B audio audio{1..3} +(Sun-compatible digital audio). MIDI devices are +.B midi00 +through +.BR midi03 , +.BI midi {0..3} \fR, +.BI rmidi {0..3} \fR, +.BI smpte {0..3} \fR. +In addition, devices +.B mpu401data and -.BR audio . +.B mpu401stat +are created. .TP .I pcaudio Devices for the PC Speaker sound driver. These are -.BR pcmixer . +.BR pcmixer , .BR pxsp , and .BR pcaudio . +.SH VIDEO DEVICES .TP -.B Miscellaneous +.B fb +Creates framebuffer devices +.BI fb {0..7} \fR, +.BI fb {0..7} current \fR, +.BI fb {0..7} autodetect \fR. .TP -.I sg +.B fb{0..7} +If the framebuffer number +.I x +is specifed, a group of +.BI fb x user {0..7} +devices is created. +.TP +.B 3dfx +is the 3Dfx Voodoo Graphics device. +.TP +.B agpgart +AGP Graphics Address Remapping Table +.TP +.I "video video4linux v4l radio" +Each of these keywords produces the same result: +Video capture/overlay devices +.BI video {0..63} \fR, +Radio devices +.BI radio {0..63} \fR, +Teletext devices +.BI vtx {0..31} \fR, +and Vertical blank interrupt devices +.BI vbi {0..31} \fR. +In addition, the +.BR winradio0 " and " winradio1 " devices," +and +.BR vtx " and " vttuner " devices," +and symlinks +.BR "radio video" " and " vbi +are created. +.TP +.BI srnd +miroMEDIA Surround board devices +.BR srnd0 " and " srnd1 . +.TP +.B fgrab +Matrox Meteor frame grabber {2.6}. Creates +.BR mmetfgrab , +.BR wvisfgrab , +.BR iscc0 , +.BR iscc1 , +.BR isccctl0 , +.BR isccctl1 , +.BR dcxx0 , +and +.BR dcxx1 . +.SH MISCELLANEOUS DEVICES +.TP +.IR sg " or " sg-all Generic SCSI devices. The devices created are -.B sg0 through -.BR sg7 . -These -allow arbitary commands to be sent to any SCSI device. This allows for -querying information about the device, or controlling SCSI devices that -are not one of disk, tape or CDROM (e.g. scanner, writeable CDROM). +.B sg0 +through +.BR sg16 . +These allow arbitary commands to be sent to any SCSI device, to query +information or control SCSI devices that are not disk, tape or CDROM +(for example, scanner or writeable CDROM). .TP .I fd To allow an arbitary program to be fed input from file descriptor @@ -363,17 +860,22 @@ To allow an arbitary program to be fed input from file descriptor use .BI /dev/fd/ x as the file name. This also creates -BR /dev/stdin , -BR /dev/stdout , +.BR /dev/stdin , +.BR /dev/stdout , and -BR /dev/stderr . +.BR /dev/stderr . (Note, these are just symlinks into /proc/self/fd). .TP .I ibcs2 -Devices (and symlinks) needed by the IBCS2 emulation. +Devices +.B socksys spx +(and symlinks +.BR "nfsd XOR" ) +needed by the IBCS2 emulation. .TP .I apm -Devices for power management. +.B apm_bios +Advanced Power Management BIOS device. .TP .I dcf Driver for DCF-77 radio clock. @@ -381,12 +883,351 @@ Driver for DCF-77 radio clock. .I helloworld Kernel modules demonstration device. See the modules source. .TP +.BR xfs " or " arla +Arla XFS network file system. +.TP +.B capi +CAPI 2.0 interface ports +.BI capi20 {01..20} \fR. +.TP +.B ubd +User-mode block devices +.BI ubd {0..255} \fR. +.TP +.BI nb {0..7} +Network block devices. +.TP +.B raw +Creates the raw block device interface +.B raw +device, the +.B rawctl +symlink, and +.BI raw {1..8} \fR. +.TP +.B raw1394 +IEEE 1394 (Firewire). +.TP +.B misc +This keyword creates all the following devices. You may find the +device explanations in other categories in this man page, many +under OTHER DEVICES below. +.BR logibm , +.BR psaux , +.BR inportbm , +.BR atibm , +.BR jbm , +.BR amigamouse , +.BR atarimouse , +.BR sunmouse , +.BR amigamouse1 , +.BR smouse , +.BR pc110pad , +.BR adbmouse , +.BR beep , +.BR modreq , +.BR watchdog , +.BR temperature , +.BR hwtrap , +.BR exttrp , +.BR apm_bios , +.BR rtc , +.BR openprom , +.BR relay8 , +.BR relay16 , +.BR msr , +.BR pciconf , +.BR nvram , +.BR hfmodem , +.BR led , +.BR mergemem , +.BR pmu . +.TP .B "Network Devices" Linux used to have devices in /dev for controlling network devices, but that is no longer the case. To see what network devices are known by the kernel, look at /proc/net/dev. +.SH OTHER DEVICES +.TP +Many of these devices are architecture-specific. +.TP +.I scc +Z8530 HDLC driver (HAM radio) +.TP +.I bc +Baycom radio modem (HAM radio) +.TP +.IR cfs0 " or " cfs " or " coda +Coda network file system +.TP +.I sunmouse +Sun mouse +.TP +.I smouse +Simple serial mouse driver +.TP +.I pc110pad +IBM PC-110 digitizer pad +.TP +.I vrtpanel +Vr41xx embedded touch panel +.TP +.I vpcmouse +Connectix Virtual PC Mouse +.TP +.I beep +Fancy beep device +.TP +.I modreq +Kernel module load request {2.6} +.TP +.I watchdog +Watchdog timer port +.TP +.I temperature +Machine internal temperature +.TP +.I hwtrap +Hardware fault trap +.TP +.I exttrp +External device trap +.TP +.I rtc +Real Time Clock +.TP +.I efirtc +Real Time Clock +.TP +.I openprom +SPARC OpenBoot PROM +.TP +.I relay8 +Berkshire Products Octal relay card +.TP +.I relay16 +Berkshire Products ISO-16 relay card +.TP +.I msr +x86 model-specific registers {2.6} +.TP +.I pciconf +PCI configuration space +.TP +.I nvram +Non-volatile configuration RAM +.TP +.I hfmodem +Soundcard shortwave modem control {2.6} +.TP +.I graphics +Linux/SGI graphics device +.TP +.I opengl +Linux/SGI OpenGL pipe +.TP +.I gfx +Linux/SGI graphics effects device +.TP +.I lcd +Front panel LCD display +.TP +.I led +Front panel LEDs +.TP +.I mergemem +Memory merge device +.TP +.I pmu +Macintosh PowerBook power manager +.TP +.I isictl +MultiTech ISICom serial control +.TP +.I ac +Applicom Intl Profibus card +.TP +.I nwbutton +Netwinder external button +.TP +.I nwdebug +Netwinder debug interface +.TP +.I nwflash +Netwinder flash memory +.TP +.I userdma +User-space DMA access +.TP +.I smbus +System Management Bus +.TP +.I lik +Logitech Internet Keyboard +.TP +.I ipmo +Intel Intelligent Platform Management +.TP +.I vmmon +VMWare virtual machine monitor +.TP +.I tcldrv +Technology Concepts serial control +.TP +.I specialix_sxctl +Specialix serial control +.TP +.I specialix_rioctl +Specialix RIO serial control +.TP +.IR smapi " or " thinkpad +IBM Thinkpad +.B smapi +device, and a symlink +.BR thinkpad . +.TP +.I srripc +QNX4 API IPC manager +.TP +.I usemaclone +Semaphore clone device +.TP +.IR ipmi " or " ipmikcs +Intelligent Platform Management +.TP +.I uctrl +SPARCbook 3 microcontroller +.TP +.I gtrsc +Gorgy Timing radio clock +.TP +.I cbm +Serial CBM bus +.TP +.I jsflash +JavaStation OS flash SIMM +.TP +.I xsvc +High-speed shared-mem/semaphore service +.TP +.I vrbuttons +Vr41xx button input device +.TP +.I toshiba +Toshiba laptop SMM support +.TP +.I perfctr +Performance-monitoring counters +.TP +.I intel_rng +Intel i8x0 random number generator +.TP +.I atomicps +Atomic shapshot of process state data +.TP +.I irnet +IrNET device +.TP +.I smbusbios +SMBus BIOS +.TP +.I ussp_ctl +User space serial port control +.TP +.I crash +Mission Critical Linux crash dump facility +.TP +.I nas_xbus +NAS xbus LCD/buttons access +.TP +.I d7s +SPARC 7-segment display +.TP +.I zkshim +Zero-Knowledge network shim control +.TP +.I sexec +Signed executable interface +.TP +.I kchuid +Inter-process chuid control +.TP +.I mptctl +Message passing technology (MPT) control +.TP +.I button/gulpb +Transmeta GULP-B buttons +.TP +.I compaq/cpqphpc +Compaq PCI Hot Plug Controller +.TP +.I compaq/cpqrid +Compaq Remote InsightDriver +.TP +.I elographics/e2201 +Elographics touchscreen E271-2201 +.TP +.I fujitsu/apanel +Fujitsu/Siemens application panel +.TP +.I i2o/ctl +I2O configuration manager +.TP +.I impi/bt +IMPI coprocessor block transfer +.TP +.I impi/smic +IMPI coprocessor stream interface +.TP +.I input/mouse +Linux/SGI Irix emulation mouse +.TP +.I input/keyboard +Linux/SGI Irix emulation keyboard +.TP +.I modems/mwave +MWave modem firmware upload +.TP +.I mvista/hssdsi +Montavista PICMG hot swap system driver +.TP +.I mvista/hasi +Montavista PICMG high availability +.TP +.I net/tun +TAP/TUN network device +.TP +.I ni/natmotn +National Instruments Motion +.TP +.I scanners/cuecat +:CueCat barcode scanner +.TP +.I touchscreen/ucb1x00 +UCB 1x00 touchscreen +.TP +.I touchscreen/mk712 +MK712 touchscreen +.TP +.I video/em8300 +EM8300 DVD decoder control +.TP +.I video/em8300_mv +EM8300 DVD decoder video +.TP +.I video/em8300_ma +EM8300 DVD decoder audio +.TP +.I video/em8300_sp +EM8300 DVD decoder subpicture +.TP +.I watchdogs/{0..3} +Watchdog devices 0 through 3 + .SH "SEE ALSO" Linux Allocated Devices, maintained by H.\ Peter Anvin, -<Peter.Anvin@linux.org>. +<Peter.Anvin@linux.org>, and devices.txt in the Linux +kernel source. .SH AUTHOR -Nick Holloway +Nick Holloway, rewritten and updated by Chris Tillman + diff --git a/net-scripts/conf.d/net b/net-scripts/conf.d/net new file mode 100644 index 0000000..54337cf --- /dev/null +++ b/net-scripts/conf.d/net @@ -0,0 +1,4 @@ +# This blank configuration will automatically use DHCP for any net.* +# scripts in /etc/init.d. To create a more complete configuration, +# please review /etc/conf.d/net.example and save your configuration +# in /etc/conf.d/net (this file :]!). diff --git a/net-scripts/conf.d/net.example b/net-scripts/conf.d/net.example new file mode 100644 index 0000000..42bc2e3 --- /dev/null +++ b/net-scripts/conf.d/net.example @@ -0,0 +1,617 @@ +############################################################################## +# QUICK-START +# +# The quickest start is if you want to use DHCP. +# In that case, everything should work out of the box, no configuration +# necessary, though the startup script will warn you that you haven't +# specified anything. +# +# If you want to use a static address or use DHCP explicitly, jump +# down to the section labelled INTERFACE HANDLERS. +# +# If you want to do anything more fancy, you should take the time to +# read through the rest of this file. + +############################################################################## +# DEFAULTS +# +# hotplug_eth0="yes" +# Do we allow hotplug to bring up interfaces or not? The default is we do, +# otherwise put no in the above value. +# NOTE: hotplug just has to be installed for hotplugging to work - it does +# not matter if it's in any runlevel or not. + +############################################################################## +# MODULES +# +# We now support modular networking scripts which means we can easily +# add support for new interface types and modules while keeping +# compatability with existing ones. +# +# Modules load by default if the package they need is installed. If +# you specify a module here that doesn't have it's package installed +# then you get an error stating which package you need to install. +# Ideally, you only use the modules setting when you have two or more +# packages installed that supply the same service. +# +# In other words, you probably should DO NOTHING HERE... + +# Prefer ifconfig over iproute2 +#modules=( "iproute2" ) + +# You can also specify other modules for an interface +# In this case we prefer udhcpc over dhcpcd +#modules_eth0=( "udhcpc" ) + +# You can also specify which modules not to use - for example you may be +# using a supplicant or linux-wlan-ng to control wireless configuration but +# you still want to configure network settings per ESSID associated with. +#modules=( "!iwconfig" "!wpa_supplicant" ) +# IMPORTANT: If you need the above, please disable modules in that order + + +############################################################################## +# INTERFACE HANDLERS +# +# We provide two interface handlers presently: ifconfig and iproute2. +# You need one of these to do any kind of network configuration. +# For ifconfig support, emerge sys-apps/net-tools +# For iproute2 support, emerge sys-apps/iproute2 + +# If you don't specify an interface then we prefer iproute2 if it's installed +# To prefer ifconfig over iproute2 +#modules=( "ifconfig" ) + +# For a static configuration, use something like this +# (They all do exactly the same thing btw) +#config_eth0=( "192.168.0.2/24" ) +#config_eth0=( "192.168.0.2 netmask 255.255.255.0" ) + +# We can also specify a broadcast +#config_eth0=( "192.168.0.2/24 brd 192.168.0.255" ) +#config_eth0=( "192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255" ) + +# If you need more than one address, you can use something like this +# NOTE: ifconfig creates an aliased device for each extra IPv4 address +# (eth0:1, eth0:2, etc) +# iproute2 does not do this as there is no need to +#config_eth0=( +# "192.168.0.2/24" +# "192.168.0.3/24" +# "192.168.0.4/24" +#) +# Or you can use sequence expresions +#config_eth0=( "192.168.0.{2..4}/24" ) +# which does the same as above. Be careful though as if you use this and +# fallbacks, you have to ensure that both end up with the same number of +# values otherwise your fallback won't work correctly. + +# You can also use IPv6 addresses +# (you should always specficy a prefix length with IPv6 here) +#config_eth0=( +# "192.168.0.2/24" +# "4321:0:1:2:3:4:567:89ab/64" +# "4321:0:1:2:3:4:567:89ac/64" +#) + +# If you wish to keep existing addresses + routing and the interface is up, +# you can specify a noop (no operation). If the interface is down or there +# are no addresses assigned, then we move onto the next step (default dhcp) +# This is useful when configuring your interface with a kernel command line +# or similar +#config_eth0=( "noop" "192.168.0.2/24" ) + +# If you don't want ANY address (only useful when calling for advanced stuff) +#config_eth0=( "null" ) + +# Here's how todo routing if you need it - the below sets the default gateway +# and eth0 to be the default route for IPv6 unicast addresses +#routes_eth0=( +# "default via 192.168.0.1" +# "::/0" +#) + +# If a specified module fails (like dhcp - see below), you can specify a +# fallback like so +#fallback_eth0=( "192.168.0.2 netmask 255.255.255.0" ) +#fallback_route_eth0=( "default via 192.168.0.1" ) + +# NOTE: fallback entry must match the entry location in config_eth0 +# As such you can only have one fallback route. + +# Some users may need to alter the MTU - here's how +#mtu_eth0="1500" + +############################################################################## +# OPTIONAL MODULES + +# INTERFACE RENAMING +# There is no consistent device renaming scheme for Linux. +# The preferred way of naming devices is via the kernel module directly or +# by using udev (http://www.reactivated.net/udevrules.php) + +# If you are unable to write udev rules, then we do provide a way of renaming +# the interface based on it's MAC address, but it is not optimal. +# Here is how to rename an interface whose MAC address is 00:11:22:33:44:55 +# to foo1 +#rename_001122334455="foo1" + +# You can also do this based on current device name - although this is not +# recommended. Here we rename eth1 to foo2. +#rename_eth1="foo2" + +#----------------------------------------------------------------------------- +# WIRELESS (802.11 support) +# Wireless can be provided by iwconfig or wpa_supplicant + +# iwconfig +# emerge net-wireless/wireless-tools +# Wireless options are held in /etc/conf.d/wireless - but could be here too +# Consult the sample file /etc/conf.d/wireless.example for instructions +# iwconfig is the default + +# wpa_supplicant +# emerge net-wireless/wpa-supplicant +# Wireless options are held in /etc/wpa_supplicant.conf +# Consult the sample file /etc/wpa_supplicant.conf.example for instructions +# To choose wpa_supplicant over iwconfig +#modules=( "wpa_supplicant" ) +# To configure wpa_supplicant +#wpa_supplicant_eth0="-Dprism54" # For Prism54 based cards +#wpa_supplicant_ath0="-Dmadwifi" # For Atheros based cards +# Consult wpa_supplicant for more drivers +# By default we give wpa_suppliant 60 seconds to associate and authenticate +# 0 means we wait indefinitely +#associate_timeout_eth0=60 + +# GENERIC WIRELESS OPTIONS +# PLEASE READ THE INSTRUCTIONS IN /etc/conf.d/wireless.example FOR +# HOW TO USE THIS ESSID VARIABLE +# You can also override any settings found here per ESSID - which is very +# handy if you use different networks a lot +#config_ESSID=( "dhcp" ) +#dhcpcd_ESSID="-t 5" + +# Setting name/domain server causes /etc/resolv.conf to be overwritten +# Note that if DHCP is used, and you want this to take precedence then +# set dhcp_ESSID="nodns" +#dns_servers_ESSID=( "192.168.0.1" "192.168.0.2" ) +#dns_domain_ESSID="some.domain" +#dns_search_ESSID="search.this.domain search.that.domain" +# Please check the man page for resolv.conf for more information +# as domain and search are mutually exclusive. + +# You can also override any settings found here per MAC address of the AP +# incase you use Access Points with the same ESSID but need different +# networking configs. Below is an example - of course you use the same +# method with other variables +#mac_config_001122334455=( "dhcp" ) +#mac_dhcpcd_001122334455="-t 10" +#mac_dns_servers_001122334455=( "192.168.0.1" "192.168.0.2" ) + +# When an interface has been associated with an Access Point, a global +# variable called ESSID is set to the Access Point's ESSID for use in the +# pre/post user functions below (although it's not available in preup as you +# won't have associated then) + +# If you're using anything else to configure wireless on your interface AND +# you have installed any of the above packages, you need to disable them +#modules=( "!iwconfig" "!wpa_supplicant" ) + +#----------------------------------------------------------------------------- +# DHCP +# DHCP can be provided by dhcpcd, dhclient, udhcpc or pump +# +# dhclient: emerge net-misc/dhcp +# dhcpcd: emerge net-misc/dhcpcd +# pump: emerge net-misc/pump +# udhcpc: emerge net-misc/udhcp + +# If you have more than one DHCP client installed, you need to specify which +# one to use - otherwise we default to dhcpcd if available +#modules=( "udhcpc" ) # to select udhcpc over dhcpcd +# +# Notes: +# - dhcpcd, udhcpc and pump send the current hostname +# to the DHCP server by default +# pump always sends the current hostname - see below to disable +# udhcpc and dhcpcd from doing this +# - dhcpcd does not daemonize when the lease time is infinite +# - udhcp-0.9.3-r3 and earlier does not support getting NTP servers +# - dhclient does not support getting NTP servers +# - pump does not support getting NIS servers +# - DHCP tends to erase any existing device information - so add +# static addresses after dhcp if you need them +# - dhclient and udhcpc can set other resolv.conf options such as "option" +# and "sortlist"- see the System module for more details + +# Regardless of which DHCP client you prefer, you configure them the +# same way using one of following depending on which interface modules +# you're using. +#config_eth0=( "dhcp" ) + +# For passing custom options to dhcpcd use something like the following. This +# example reduces the timeout for retrieving an address from 60 seconds (the +# default) to 10 seconds. +#dhcpcd_eth0="-t 10" + +# dhclient, udhcpc and pump don't have many runtime options +# You can pass options to them in a similar manner to dhcpcd though +#dhclient_eth0="..." +#udhcpc_eth0="..." +#pump_eth0="..." + +# To set options for dhclient, you need to have an /etc/dhclient.conf file +# See the dhclient man page for details + +# GENERIC DHCP OPTIONS +# Set generic DHCP options like so +#dhcp_eth0="release nodns nontp nonis nogateway nosendhost" + +# This tells the dhcp client to release it's lease when it stops, not to +# overwrite dns, ntp and nis settings, not to set a default route and not to +# send the current hostname to the dhcp server and when it starts. +# You can use any combination of the above options - the default is not to +# use any of them. + +# DHCLIENT +# dhclient can modify /etc/dhclient.conf (or the file specified by the -cf +# option) with the current hostname and to strip any script lines. To enable +# this, add dhclient_edit_config="yes" to /etc/conf.d/net + +#----------------------------------------------------------------------------- +# For APIPA support, emerge net-misc/iputils or net-analyzer/arping + +# APIPA is a module that tries to find a free address in the range +# 169.254.0.0-169.254.255.255 by arping a random address in that range on the +# interface. If no reply is found then we assign that address to the interface + +# This is only useful for LANs where there is no DHCP server and you don't +# connect directly to the internet. +#config_eth0=( "dhcp" ) +#fallback_eth0=( "apipa" ) + +#----------------------------------------------------------------------------- +# ARPING Gateway configuration +# and +# Automatic Private IP Addressing (APIPA) +# For arpingnet / apipa support, emerge net-misc/iputils or net-analyzer/arping +# +# This is a module that tries to find a gateway IP. If it exists then we use +# that gateways configuration for our own. For the configuration variables +# simply ensure that each ocet is zero padded and the dots are removed. +# Below is an example. +# +#arping_eth0="192.168.0.1 10.0.0.1" +#config_192168000001=( "192.168.0.2/24" ) +#routes_192168000001=( "default via 192.168.0.1" ) +#dns_servers_192168000001=( "192.168.0.1" ) +#config_010000000001=( "10.0.0.254/8" ) +#routes_010000000001=( "default via 10.0.0.1" ) +#dns_servers_010000000001=( "10.0.0.1" ) + +# If we don't find any gateways (or there are none configured) then we try and +# use APIPA to find a free address in the range 169.254.0.0-169.254.255.255 +# by arping a random address in that range on the interface. If no reply is +# found then we assign that address to the interface. + +# This is only useful for LANs where there is no DHCP server. +#config_eth0=( "arping" ) + +# or if no DHCP server can be found +#config_eth0=( "dhcp" ) +#fallback_eth0=( "arping" ) + +#----------------------------------------------------------------------------- +# VLAN (802.1q support) +# For VLAN support, emerge net-misc/vconfig + +# Specify the VLAN numbers for the interface like so +# Please ensure your VLAN IDs are NOT zero-padded +#vlans_eth0="1 2" + +# You can also configure the VLAN - see for vconfig man page for more details +#vconfig_eth0=( "set_name_type VLAN_PLUS_VID_NO_PAD" ) +#vconfig_vlan1=( "set_flag 1" "set_egress_map 2 6" ) +#config_vlan1=( "172.16.3.1 netmask 255.255.254.0" ) +#config_vlan2=( "172.16.2.1 netmask 255.255.254.0" ) + +# NOTE: Vlans can be configured with a . in their interface names +# When configuring vlans with this name type, you need to replace . with a _ +#config_eth0.1=( "dhcp" ) - does not work +#config_eth0_1=( "dhcp" ) - does work + +#----------------------------------------------------------------------------- +# Bonding +# For link bonding/trunking emerge net-misc/ifenslave + +# To bond interfaces together +#slaves_bond0="eth0 eth1 eth2" +#config_bond0=( "null" ) # You may not want to assign an IP the the bond + +# If any of the slaves require extra configuration - for example wireless or +# ppp devices - we need to write a depend function for the bond so they get +# configured correctly. +# This is exactly the same as a depend() function in our init scripts +#depend_br0() { +# need net.eth0 net.eth1 +#} + +#----------------------------------------------------------------------------- +# ADSL +# For ADSL support, emerge net-dialup/rp-pppoe +# You should make the following settings and also put your +# username/password information in /etc/ppp/pap-secrets + +# Configure the interface to use ADSL +#config_eth0=( "adsl" ) + +# You probably won't need to edit /etc/ppp/pppoe.conf if you set this +#adsl_user_eth0="my-adsl-username" + +#----------------------------------------------------------------------------- +# ISDN +# For ISDN support, emerge net-dialup/isdn4k-utils +# You should make the following settings and also put your +# username/password information in /etc/ppp/pap-secrets + +# Configure the interface to use ISDN +#config_ippp0=( "dhcp" ) +# It's important to specify dhcp if you need it! +#config_ippp0=( "192.168.0.1/24" ) +# Otherwise, you can use a static IP + +# NOTE: The interface name must be either ippp or isdn followed by a number + +# You may need this option to set the default route +#ipppd_eth0="defaultroute" + +#----------------------------------------------------------------------------- +# MAC changer +# To set a specific MAC address +#mac_eth0="00:11:22:33:44:55" + +# For changing MAC addresses using the below, emerge net-analyzer/macchanger +# - to randomize the last 3 bytes only +#mac_eth0="random-ending" +# - to randomize between the same physical type of connection (eg fibre, +# copper, wireless) , all vendors +#mac_eth0="random-samekind" +# - to randomize between any physical type of connection (eg fibre, copper, +# wireless) , all vendors +#mac_eth0="random-anykind" +# - full randomization - WARNING: some MAC addresses generated by this may NOT +# act as expected +#mac_eth0="random-full" +# custom - passes all parameters directly to net-analyzer/macchanger +#mac_eth0="some custom set of parameters" + +# You can also set other options based on the MAC address of your network card +# Handy if you use different docking stations with laptops +#config_001122334455=( "dhcp" ) + +#----------------------------------------------------------------------------- +# TUN/TAP +# For TUN/TAP support emerge sys-apps/usermode-utilities +# +# NOTE: The interface name must be either tun or tap followed by a number +#config_tun1=( "192.168.0.1/24") + +# For passing custom options to tunctl use something like the following. This +# example sets the owner to adm +#tunctl_tun1="-u adm" + +#----------------------------------------------------------------------------- +# Bridging (802.1d) +# For bridging support emerge net-misc/bridge-utils + +# To add ports to bridge br0 +#bridge_br0="eth0 eth1" +# or dynamically add them when the interface comes up +#bridge_add_eth0="br0" +#bridge_add_eth1="br0" + +# You need to configure the ports to null values so dhcp does not get started +#config_eth0=( "null" ) +#config_eth1=( "null" ) + +# Finally give the bridge an address - dhcp or a static IP +#config_br0=( "dhcp" ) # may not work when adding ports dynamically +#config_br0=( "192.168.0.1/24" ) + +# If any of the ports require extra configuration - for example wireless or +# ppp devices - we need to write a depend function for the bridge so they get +# configured correctly. +# This is exactly the same as a depend() function in our init scripts +#depend_br0() { +# need net.eth0 net.eth1 +#} + +# NOTE: This creates an interface called br0 - you can give the interface +# any name you like + +# Below is an example of configuring the bridge +# Consult "man brctl" for more details +#brctl_br0=( "setfd 0" "sethello 0" "stp off" ) + +#----------------------------------------------------------------------------- +# Tunnelling +# For GRE tunnels +#iptunnel_vpn0="mode gre remote 207.170.82.1 key 0xffffffff ttl 255" + +# For IPIP tunnels +#iptunnel_vpn0="mode ipip remote 207.170.82.2 ttl 255" + +# To configure the interface +#config_vpn0=( "192.168.0.2 pointopoint 192.168.1.2" ) # ifconfig style +#config_vpn0=( "192.168.0.2 peer 192.168.1.1" ) # iproute2 style + +#----------------------------------------------------------------------------- +# System +# For configuring system specifics such as domain, dns, ntp and nis servers +# It's rare that you would need todo this, but you can anyway. +# This is most benefit to wireless users who don't use DHCP so they can change +# their configs based on ESSID. See wireless.example for more details + +# To use dns settings such as these, dns_servers_eth0 must be set! +# If you omit the _eth0 suffix, then it applies to all interfaces unless +# overridden by the interface suffix. +# dns_domain_eth0="your.domain" +# dns_servers_eth0="192.168.0.2 192.168.0.3" +# dns_search_eth0="this.domain that.domain" +# dns_options_eth0=( "timeout 1" "rotate" ) +# dns_sortlist_eth0="130.155.160.0/255.255.240.0 130.155.0.0" +# See the man page for resolv.conf for details about the options and sortlist +# directives + +# ntp_servers_eth0="192.168.0.2 192.168.0.3" + +# nis_domain_eth0="domain" +# nis_servers_eth0="192.168.0.2 192.168.0.3" + +#----------------------------------------------------------------------------- +# Cable in/out detection +# Sometimes the cable is in, others it's out. Obviously you don't want to +# restart net.eth0 every time when you plug it in either. +# +# netplug is a package that detects this and requires no extra configuration +# on your part. +# emerge sys-apps/netplug +# or +# emerge sys-apps/ifplugd +# and you're done :) + +# By default we wait 10 seconds for netplug to configure the interface for us +# if it doesn't, we abort but leave netplug running and the net.eth0 service +# marked as inactive so when a cable is plugged in it starts fine. +# plug_timeout="10" + +# If you don't want to use netplug on a specific interface but you have it +# installed, you can disable it for that interface via the modules statement +# modules_eth0=( "!netplug" ) +# You can do the same for ifplugd + +# To use specific ifplugd options, fex specifying wiress mode +#ifplugd_eth0="--api-mode wlan" +# man ifplugd for more options + +############################################################################## +# ADVANCED CONFIGURATION +# +# Four functions can be defined which will be called surrounding the +# start/stop operations. The functions are called with the interface +# name first so that one function can control multiple adapters. An extra two +# functions can be defined when an interface fails to start or stop. +# +# The return values for the preup and predown functions should be 0 +# (success) to indicate that configuration or deconfiguration of the +# interface can continue. If preup returns a non-zero value, then +# interface configuration will be aborted. If predown returns a +# non-zero value, then the interface will not be allowed to continue +# deconfiguration. +# +# The return values for the postup, postdown, failup and faildown functions are +# ignored since there's nothing to do if they indicate failure. +# +# ${IFACE} is set to the interface being brought up/down +# ${IFVAR} is ${IFACE} converted to variable name bash allows + +#preup() { +# # Test for link on the interface prior to bringing it up. This +# # only works on some network adapters and requires the mii-diag +# # package to be installed. +# if mii-tool ${IFACE} 2> /dev/null | grep -q 'no link'; then +# ewarn "No link on ${IFACE}, aborting configuration" +# return 1 +# fi +# +# # Test for link on the interface prior to bringing it up. This +# # only works on some network adapters and requires the ethtool +# # package to be installed. +# if ethtool ${IFACE} | grep -q 'Link detected: no'; then +# ewarn "No link on ${IFACE}, aborting configuration" +# return 1 +# fi +# +# # Remember to return 0 on success +# return 0 +#} + +#predown() { +# # The default in the script is to test for NFS root and disallow +# # downing interfaces in that case. Note that if you specify a +# # predown() function you will override that logic. Here it is, in +# # case you still want it... +# if is_net_fs /; then +# eerror "root filesystem is network mounted -- can't stop ${IFACE}" +# return 1 +# fi +# +# # Remember to return 0 on success +# return 0 +#} + +#postup() { +# # This function could be used, for example, to register with a +# # dynamic DNS service. Another possibility would be to +# # send/receive mail once the interface is brought up. +# return 0 +#} + +#postdown() { +# # This function is mostly here for completeness... I haven't +# # thought of anything nifty to do with it yet ;-) +# # Return 0 always +# return 0 +#} + +#failup() { +# # This function is mostly here for completeness... I haven't +# # thought of anything nifty to do with it yet ;-) +#} + +#faildown() { +# # This function is mostly here for completeness... I haven't +# # thought of anything nifty to do with it yet ;-) +#} + +############################################################################## +# FORCING MODULES +# The Big Fat Warning :- If you use module forcing do not complain to us or +# file bugs about it not working! +# +# Loading modules is a slow afair - we have to check each one for the following +# 1) Code sanity +# 2) Has the required package been emerged? +# 3) Has it modified anything? +# 4) Have all the dependant modules been loaded? + +# Then we have to strip out the conflicting modules based on user preference +# and default configuration and sort them into the correct order. +# Finally we check the end result for dependancies. + +# This, of course, takes valuable CPU time so we provide module forcing as a +# means to speed things up. We still do *some* checking but not much. + +# It is essential that you force modules in the correct order and supply all +# the modules you need. You must always supply an interface module - we +# supply ifconfig or iproute2. + +# The Big Fat Warning :- If you use module forcing do not complain to us or +# file bugs about it not working! + +# Now that we've warned you twice, here's how to do it +#modules_force=( "ifconfig" ) +#modules_force=( "iproute2" "dhcpcd" ) + +# We can also apply this to a specific interface +#modules_force_eth1=( "iproute2" ) + +# The below will not work +#modules_force=( "dhcpcd" ) +# No interface (ifconfig/iproute2) +#modules_force=( "ifconfig" "essidnet" "iwconfig" ) +# Although it will not crash, essidnet will not work as it has to come after +# iwconfig +#modules_force=( "iproute2" "ifconfig" ) +# The interface will be setup twice which will cause problems diff --git a/net-scripts/conf.d/wireless.example b/net-scripts/conf.d/wireless.example new file mode 100644 index 0000000..18e27b5 --- /dev/null +++ b/net-scripts/conf.d/wireless.example @@ -0,0 +1,283 @@ +# /etc/conf.d/wireless: +# Global wireless config file for net.* rc-scripts + +############################################################################## +# IMPORTANT +# linux-wlan-ng is not supported as they have their own configuration program +# ensure that /etc/conf.d/net has the entry "!iwconfig" in it's modules line +# Try and use an alternative driver if you need to use this - hostap-driver +# supports non-usb linux-wlan-ng driven devices +############################################################################## + +############################################################################## +# HINTS +############################################################################## +# Remember to change eth0 to your wireless interface which may be +# eth0, eth1, wlan0, ath0 - you get the idea. If you're not sure +# you can type "iwconfig" at the command prompt and it will tell you which +# interfaces are wireless. +# Say that your wireless interface is ath0 - the line +# #essid_eth0="any" +# becomes +# #essid_ath0="any" +# +# Remember to change ESSID to your ESSID. +# Say that your ESSID is My NET - the line +# #key_ESSID="s:passkey" +# becomes +# #key_My_NET="s:passkey" +# Notice that the space has changed to an underscore - do the same with all +# characters not in a-z A-Z (english alphabet) 0-9. This only applies to +# variables and not values. +# +# Any ESSID's in values like essid_eth0="My NET" may need to be escaped +# This means placing the character \ before the character +# \" need to be escaped for example +# So if your ESSID is +# My "\ NET +# it becomes +# My \"\\ NET +# for example +# #essid_eth0="My\"\\NET" +# +# So using the above we can use +# #dns_domain_My____NET="My\"\\NET" +# which is an invalid dns domain, but shows the how to use the variable +# structure +# +# As a final note, most users will just need to set the following options +# key_ESSID1="s:yourkeyhere enc open" # s: means a text key +# key_ESSID2="aaaa-bbbb-cccc-dd" # no s: means a hex key +# preferred_aps=( "ESSID1" "ESSID2" ) +# +# Clear? Good. Now configure your wireless network below +######################################################### + +############################################################################## +# SETTINGS +############################################################################## +# Hard code an ESSID to an interface - leave this unset if you wish the driver +# to scan for available Access Points +# Set to "any" to connect to any ESSID - the driver picks an Access Point +# This needs to be done when the driver doesn't support scanning +# This may work for drivers that don't support scanning but you need automatic +# AP association +# I would only set this as a last resort really - use the preferred_aps +# setting at the bottom of this file + +# However, using ad-hoc (without scanning for APs) and master mode +# do require the ESSID to be set - do this here +#essid_eth0="any" + +# Set the mode of the interface (managed, ad-hoc, master or auto) +# The default is auto +# If it's ad-hoc or master you also may need to specify the channel below +#mode_eth0="auto" + +# If managed mode fails, drop to ad-hoc mode with the below ESSID? +#adhoc_essid_eth0="WLAN" + +#Channel can be set (1-14), but defaults to 3 if not set. +# +# The below is taken verbatim from the BSD wavelan documentation found at +# http://www.netbsd.org/Documentation/network/wavelan.html +# There are 14 channels possible; We are told that channels 1-11 are legal for +# North America, channels 1-13 for most of Europe, channels 10-13 for France, +# and only channel 14 for Japan. If in doubt, please refer to the documentation +# that came with your card or access point. Make sure that the channel you +# select is the same channel your access point (or the other card in an ad-hoc +# network) is on. The default for cards sold in North America and most of Europe +# is 3; the default for cards sold in France is 11, and the default for cards +# sold in Japan is 14. +#channel_eth0="3" + +# Setup any other config commands. This is basically the iwconfig argument +# without the iwconfig $iface +#iwconfig_eth0="" + +# Set private driver ioctls. This is basically the iwpriv argument without +# the iwpriv $iface +#iwpriv_eth0="" + +# Seconds to wait before scanning +# Some drivers need to wait until they have finished "loading" +# before they can scan - otherwise they error and claim that they cannot scan +# or resource is unavailable. The default is to wait zero seconds +#sleep_scan_eth0="1" + +# Seconds to wait until associated. The default is to wait 10 seconds. +# 0 means wait indefinitely. WARNING : this can cause an infinite delay when +# booting. +#associate_timeout_eth0="5" + +# By default a successful association in Managed mode sets the MAC +# address of the AP connected to. However, some drivers (namely +# the ipw2100) don't set an invalid MAC address when association +# fails - so we need to check on link quality which some drivers +# don't report properly either. +# So if you have connection problems try flipping this setting +# Valid options are MAC, quality and all - defaults to MAC +#associate_test_eth0="MAC" + +# Some driver/card combinations need to scan in Ad-Hoc mode +# After scanning, the mode is reset to the one defined above +#scan_mode_eth0="Ad-Hoc" + +# Below you can define private ioctls to run before and after scanning +# Format is the same as the iwpriv_eth0 above +# This is needed for the HostAP drivers +#iwpriv_scan_pre_eth0="host_roaming 2" +#iwpriv_scan_post_eth0="host_roaming 0" + +# Define a WEP key per ESSID or MAC address (of the AP, not your card) +# The encryption type (open or restricted) must match the +# encryption type on the Access Point +# You can't use "any" for an ESSID here +#key_ESSID="1234-1234-1234-1234-1234-1234-56" +# or you can use strings. Passphrase IS NOT supported +# To use a string, prefix it with s: +# Note - this example also sets the encryption method to open +# which is regarded as more secure than restricted +#key_ESSID="s:foobar enc open" +#key_ESSID="s:foobar enc restricted" + +# If you have whitespace in your key, here's how to set it and use other +# commands like using open encryption. +#key_ESSID="s:'foo bar' enc open" + +# WEP key for the AP with MAC address 001122334455 +#key_001122334455="s:foobar" + +# Here are some more examples of keys as some users find others work +# and some don't where they should all do the same thing +#key_ESSID="open s:foobar" +#key_ESSID="open 1234-5678-9012" +#key_ESSID="s:foobar enc open" +#key_ESSID="1234-5678-9012 enc open" + +# You may want to set muliple keys - here's an example +# It sets 4 keys on the card and instructs to use key 2 by default +#key_ESSID="[1] s:passkey1 key [2] s:passkey2 key [3] s:passkey3 key [4] s:passkey4 key [2]" + +# You can also override the interface settings found in /etc/conf.d/net +# per ESSID - which is very handy if you use different networks a lot +#config_ESSID=( "dhcp" ) +#dhcpcd_ESSID="-t 5" +#routes_ESSID=() +#fallback_ESSID=() + +# Setting name/domain server causes /etc/resolv.conf to be overwritten +# Note that if DHCP is used, and you want this to take precedence then +# please put -R in your dhcpcd options +#dns_servers_ESSID=( "192.168.0.1" "192.168.0.2" ) +#dns_domain_ESSID="some.domain" +#dns_search_path_ESSID="search.this.domain search.that.domain" +# Please check the man page for resolv.conf for more information +# as domain and search (searchdomains) are mutually exclusive and +# searchdomains takes precedence + +# You can also set any of the /etc/conf.d/net variables per MAC address +# incase you use Access Points with the same ESSID but need different +# networking configs. Below is an example - of course you use the same +# method with other variables +#config_001122334455=( "dhcp" ) +#dhcpcd_001122334455="-t 10" +#dns_servers_001122334455=( "192.168.0.1" "192.168.0.2" ) + +# Map a MAC address to an ESSID +# This is used when the Access Point is not broadcasting it's ESSID +# WARNING: This will override the ESSID being broadcast due to some +# Access Points sending an ESSID even when they have been configured +# not to! +# Change 001122334455 to the MAC address and ESSID to the ESSID +# it should map to +#essid_001122334455="ESSID" + +# This lists the preferred ESSIDs to connect to in order +# ESSID's can contain any characters here as they must match the broadcast +# ESSID exactly. +# Surround each ESSID with the " character and seperate them with a space +# If the first ESSID isn't found then it moves onto the next +# If this isn't defined then it connects to the first one found +#preferred_aps=( "ESSID 1" "ESSID 2" ) + +# You can also define a preferred_aps list per interface +#preferred_aps_eth0=( "ESSID 3" "ESSID 4" ) + +# You can also say whether we only connect to preferred APs or not +# Values are "any", "preferredonly", "forcepreferred", "forcepreferredonly" and "forceany" +# "any" means it will connect to visible APs in the preferred list and then any +# other available AP +# "preferredonly" means it will only connect to visible APs in the preferred list +# "forcepreferred" means it will forceably connect to APs in order if it does not find +# them in a scan +# "forcepreferredonly" means it forceably connects to the APs in order and does not bother +# to scan +# "forceany" does the same as forcepreferred + connects to any other available AP +# Default is "any" +#associate_order="any" +#associate_order_eth0="any" + +# You can define blacklisted Access Points in the same way +#blacklist_aps=( "ESSID 1" "ESSID 2" ) +#blacklist_aps_eth0=( "ESSID 3" ESSID 4" ) + +# If you have more than one wireless card, you can say if you want +# to allow each card to associate with the same Access Point or not +# Values are "yes" and "no" +# Default is "yes" +#unique_ap="yes" +#unique_ap_eth0="yes" + +# IMPORTANT: preferred_only, blacklisted_aps and unique_ap only work when +# essid_eth0 is not set and your card is capable of scanning + +# NOTE: preferred_aps list ignores blacklisted_aps - so if you have +# the same ESSID in both, well, you're a bit silly :p + + +############################################################################## +# ADVANCED CONFIGURATION +# +# Two functions can be defined which will be called surrounding the +# associate function. The functions are called with the interface +# name first so that one function can control multiple adapters. +# +# The return values for the preassociate function should be 0 +# (success) to indicate that configuration or deconfiguration of the +# interface can continue. If preassociate returns a non-zero value, then +# interface configuration will be aborted. +# +# The return value for the postassociate function is ignored +# since there's nothing to do if it indicates failure. + +#preassociate() { +# # The below adds two configuration variables leap_user_ESSID +# # and leap_pass_ESSID. When they are both confiugred for the ESSID +# # being connected to then we run the CISCO LEAP script +# +# local user pass +# eval user=\"\$\{leap_user_${ESSIDVAR}\}\" +# eval pass=\"\$\{leap_pass_${ESSIDVAR}\}\" +# +# if [[ -n ${user} && -n ${pass} ]]; then +# if [[ ! -x /opt/cisco/bin/leapscript ]]; then +# eend "For LEAP support, please emerge net-misc/cisco-aironet-client-utils" +# return 1 +# fi +# einfo "Waiting for LEAP Authentication on \"${ESSID//\\\\//}\"" +# if /opt/cisco/bin/leapscript ${user} ${pass} | grep -q 'Login incorrect'; then +# ewarn "Login Failed for ${user}" +# return 1 +# fi +# fi +# +# return 0 +#} + +#postassociate() { +# # This function is mostly here for completeness... I haven't +# # thought of anything nifty to do with it yet ;-) +# # Return 0 always +# return 0 +#} diff --git a/net-scripts/net.modules.d/adsl b/net-scripts/net.modules.d/adsl new file mode 100644 index 0000000..87bf6ab --- /dev/null +++ b/net-scripts/net.modules.d/adsl @@ -0,0 +1,101 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* adsl_provides(void) +# +# Returns a string to change module definition for starting up +adsl_provides() { + echo "adsl" +} + +# void adsl_depend(void) +# +# Sets up the dependancies for the module +adsl_depend() { + after interface + before dhcp +} + +# bool adsl_check_installed(void) +# +# Returns 1 if rp-pppoe is installed, otherwise 0 +adsl_check_installed() { + [[ -x /usr/sbin/adsl-start ]] && return 0 + ${1:-false} && eerror "For ADSL support, emerge net-dialup/rp-pppoe" + return 1 +} + +# bool adsl_check_depends(void) +# +# Checks to see if we have the needed functions +adsl_check_depends() { + return 0 +} + +# bool adsl_setup_vars(char *iface) +# +# Checks to see if the ADSL script has been created or not +adsl_setup_vars() { + local iface="$1" + + # Decide which configuration to use. Hopefully there is an + # interface-specific one + cfgfile="/etc/ppp/pppoe-${iface}.conf" + [[ -f ${cfgfile} ]] || cfgfile="/etc/ppp/pppoe.conf" + + if [[ ! -f ${cfgfile} ]]; then + eerror "no pppoe.conf file found!" + eerror "Please run adsl-setup to create one" + return 1 + fi + + return 0 +} + +# bool adsl_start(char *iface) +# +# Start ADSL on an interface by calling adsl-start +# +# Returns 0 (true) when successful, non-zero otherwise +adsl_start() { + local iface="$1" user ifvar=$( bash_variable "$1" ) cfgfile + + adsl_setup_vars "${iface}" || return 1 + + # Might or might not be set in conf.d/net + eval user=\"\$\{adsl_user_${ifvar}\}\" + + # Start ADSL with the cfgfile, but override ETH and PIDFILE + einfo "Starting ADSL for ${iface}" + /usr/sbin/adsl-start <(cat "${cfgfile}"; \ + echo "ETH=${iface}"; \ + echo "PIDFILE=/var/run/adsl-${iface}.pid"; \ + [[ -n ${user} ]] && echo "USER=${user}") \ + >/dev/null + eend $? +} + +# bool adsl_stop(char *iface) +# +# Stop ADSL on an interface by calling adsl-stop +# Returns 0 when there is no ADSL to stop or we stop ADSL successfully +# Otherwise 1 +adsl_stop() { + local iface="$1" cfgfile + + adsl_check_installed || return 0 + [[ ! -f "/var/run/adsl-${iface}.pid" ]] && return 0 + + adsl_setup_vars "${iface}" || return 0 + + einfo "Stopping ADSL for ${iface}" + /usr/sbin/adsl-stop <(cat "${cfgfile}"; \ + echo "ETH=${iface}"; echo "PIDFILE=/var/run/adsl-${iface}.pid") \ + >/dev/null + eend $? +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/arping b/net-scripts/net.modules.d/arping new file mode 100644 index 0000000..f5e83c3 --- /dev/null +++ b/net-scripts/net.modules.d/arping @@ -0,0 +1,158 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* arping_provides(void) +# +# Returns a string to change module definition for starting up +arping_provides() { + echo "arping" +} + +# void arping_depend(void) +# +# Sets up the dependancies for the module +arping_depend() { + after system dhcp vlan +} + +# bool arping_check_installed(void) +# +# Returns 0 if arping or arping2 is installed, otherwise 1 +arping_check_installed() { + [[ -x /sbin/arping || -x /usr/sbin/arping2 ]] && return 0 + if ${1:-false}; then + eerror "For arping support emerge net-misc/iputils or net-analyzer/arping" + fi + return 1 +} + +# bool arping_check_depends(void) +# +# Checks to see if we have the needed functions +arping_check_depends() { + local f + + for f in interface_exists interface_up ; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "arping: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool address_exists(char *interface, char *address) +# +# Returns 0 if the address on the interface responds to an arping +# 1 if not - packets defaults to 1 +# If neither arping (net-misc/iputils) or arping2 (net-analyzer/arping) +# is installed then we return 1 +address_exists() { + local iface="$1" address="${2%%/*}" i + + # We only handle IPv4 addresses + [[ ${address} != *.*.*.* ]] && return 1 + + # We need to bring the interface up to test + interface_up "${iface}" + + if [[ -x /sbin/arping ]]; then + /sbin/arping -q -c 2 -w 3 -D -f -I "${iface}" "${address}" \ + &>/dev/null || return 0 + elif [[ -x /usr/sbin/arping2 ]]; then + for (( i=0; i<3; i++ )); do + /usr/sbin/arping2 -0 -c 1 -i "${iface}" "${address}" \ + &>/dev/null && return 0 + done + fi + return 1 +} + +# bool arping_gateways(void) +# +# arpings a list of gateways +# If one is foung then apply it's configuration +arping_gateways() { + local gateways x conf i + + eval gateways=\"\$\{arping_${ifvar}\}\" + [[ -z ${gateways} ]] && return 1 + + einfo "Pinging gateways on ${iface} for configuration" + eindent + + for x in ${gateways}; do + vebegin "${x}" + if address_exists "${iface}" "${x}" ; then + for i in ${x//./ } ; do + if [[ ${#i} == "2" ]]; then + conf="${conf}0${i}" + elif [[ ${#i} == "1" ]]; then + conf="${conf}00${i}" + else + conf="${conf}${i}" + fi + done + veend 0 + eoutdent + veinfo "Configuring ${iface} for ${x}" + configure_variables "${iface}" "${conf}" + return 0 + fi + veend 1 + done + + eoutdent + return 1 +} + +# bool arping_apipa(char *iface) +# +# Tries to locate an address in the 169.254.0.0 netmask 169.254.255.255 range +arping_apipa() { + local iface="$1" i1 i2 addr i=0 + + einfo "Searching for free addresses in 169.254.0.0/16" + eindent + + while [[ ${i} -lt 64516 ]]; do + (( i1=${RANDOM}%255 )) + (( i2=${RANDOM}%255 )) + + addr="169.254.${i1}.${i2}" + vebegin "${addr}/16" + if ! address_exists "${iface}" "${addr}" ; then + config[config_counter]="${addr}/16 broadcast 169.254.255.255" + (( config_counter-- )) + veend 0 + eoutdent + return 0 + fi + + (( i++ )) + done + + eerror "No free address found!" + eoutdent + return 1 +} + +# bool arping_start(char *iface) +# +# Tries to detect a config based on arpinging things +arping_start() { + local iface="$1" + + interface_exists "${iface}" true || return 1 + interface_up "${iface}" + + arping_gateways "${iface}" && return 0 + arping_apipa "${iface}" && return 0 + + return 1 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/bonding b/net-scripts/net.modules.d/bonding new file mode 100644 index 0000000..b1e7dbe --- /dev/null +++ b/net-scripts/net.modules.d/bonding @@ -0,0 +1,125 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* bonding_provides(void) +# +# Returns a string to change module definition for starting up +bonding_provides() { + echo "bonding" +} + +# void bonding_depend(void) +# +# Sets up the dependancies for the module +bonding_depend() { + after interface + before vlan dhcp arping +} + +# bool bonding_check_installed(void) +# +# Returns 1 if ifenslave is installed, otherwise 0 +bonding_check_installed() { + [[ -x /sbin/ifenslave ]] && return 0 + ${1:-false} && eerror "For link aggregation (bonding) support, emerge net-misc/ifenslave" + return 1 +} + +# bool bonding_check_depends(void) +# +# Checks to see if we have the needed functions +bonding_check_depends() { + local f + + for f in interface_exists interface_up interface_down interface_del_addresses; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "bonding: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool bonding_post_start(char *iface) +# +# Bonds the interface +bonding_pre_start() { + local iface="$1" slaves s ifvar=$( bash_variable "$1" ) + + eval slaves=\"\$\{slaves_${ifvar}\[@\]\}\" + [[ -z ${slaves} ]] && return 0 + + interface_exists "${iface}" true || return 1 + + if [[ ! -f "/proc/net/bonding/${iface}" ]]; then + eerror "${iface} is not capable of bonding" + return 1 + fi + + ebegin "Adding slaves to ${iface}" + eindent + einfo "${slaves}" + + # Check that our slaves exist + for s in ${slaves}; do + interface_exists "${s}" && continue + ewarn "interface ${s} does not exist" + return 1 + done + + # Must force the slaves to a particular state before adding them + for s in ${slaves}; do + interface_del_addresses "${s}" + interface_up "${s}" + done + + # now force the master to up + interface_up "${iface}" + + # finally add in slaves + eoutdent + /sbin/ifenslave "${iface}" ${slaves} >/dev/null + eend $? + + return 0 #important +} + +# bool bonding_pre_stop(void) +# Unbonds bonded interfaces +# +# Always returns 0 (true) +bonding_pre_stop() { + local iface="$1" slaves s + + bonding_check_installed || return 0 + + # return silently if this is not a bonding interface + [[ ! -f "/proc/net/bonding/${iface}" ]] && return 0 + + # don't trust the config, get the active list instead + slaves=$( sed -n -e 's/^Slave Interface: //p' "/proc/net/bonding/${iface}" ) + [[ -z ${slaves} ]] && return 0 + + # remove all slaves + ebegin "Removing slaves from ${iface}" + eindent + einfo "${slaves}" + eoutdent + /sbin/ifenslave -d "${iface}" ${slaves} &>${devnull} + + # reset all slaves + for s in ${slaves}; do + if interface_exists "${s}" ; then + interface_del_addresses "${s}" + interface_down "${s}" + fi + done + + eend 0 + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/bridge b/net-scripts/net.modules.d/bridge new file mode 100644 index 0000000..59f25ee --- /dev/null +++ b/net-scripts/net.modules.d/bridge @@ -0,0 +1,227 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +brctl() { + LC_ALL=C /sbin/brctl "$@" +} + +# char* bridge_provides(void) +# +# Returns a string to change module definition for starting up +bridge_provides() { + echo "bridge" +} + +# void bridge_depend(void) +# +# Sets up the dependancies for the module +bridge_depend() { + after interface tuntap + before dhcp arping +} + +# bool bridge_check_installed(void) +# +# Returns 1 if bridge is installed, otherwise 0 +bridge_check_installed() { + [[ -x /sbin/brctl ]] && return 0 + ${1:-false} && eerror "For bridge support, emerge net-misc/bridge-utils" + return 1 +} + +# bool bridge_check_depends(void) +# +# Checks to see if we have the needed functions +bridge_check_depends() { + local f + + for f in interface_down interface_del_addresses interface_set_flag; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "bridge: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# char* bridge_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +bridge_get_vars() { + echo "bridge_$1 brctl_$1" +} + +# char* bridge_get_ports(char *interface) +# +# Returns the interfaces added to the given bridge +bridge_get_ports() { + brctl show 2>/dev/null \ + | sed -n -e '/^'"$1"'/,/^\S/ { /^\('"$1"'\|\t\)/s/^.*\t//p }' +} + +# char* bridge_get_bridge(char *interface) +# +# Returns the bridge interface of the given interface +bridge_get_bridge() { + local x=$( brctl show 2>/dev/null \ + | sed -e '1 {d}; /^[^ ]/ { N }; /.*'"$1"'.*/ {s/^\([^ \t]\+\).*/\1/p}; d' ) + + local -a a=( ${x} ) + if [[ ${#a[@]} == "1" ]]; then + echo "${x}" + elif [[ $1 == "${a[3]}" ]]; then + echo "${a[0]}" + fi +} + +# bool bridge_exists(char *interface) +# +# Returns 0 if the bridge exists, otherwise 1 +bridge_exists() { + brctl show 2>/dev/null | grep -q "^$1" +} + +# bool bridge_create(char *interface) +# +# Creates the bridge - no ports are added here though +# Returns 0 on success otherwise 1 +bridge_create() { + local iface="$1" ifvar=$( bash_variable "$1" ) x i + local -a opts + + ebegin "Creating bridge ${iface}" + x=$( brctl addbr "${iface}" 2>&1 ) + if [[ -n ${x} ]]; then + if [[ ${x//Package not installed/} != "${x}" ]]; then + eend 1 "Bridging (802.1d) support is not present in this kernel" + else + eend 1 "${x}" + fi + return 1 + fi + + eval opts=( \"\$\{brctl_${ifvar}\[@\]\}\" ) + for (( i=0; i<${#opts[@]}; i++ )); do + x="${opts[i]/ / ${iface} }" + [[ ${x} == "${opts[i]}" ]] && x="${x} ${iface}" + x=$( brctl ${x} 2>&1 1>/dev/null ) + [[ -n ${x} ]] && ewarn "${x}" + done + eend 0 +} + +# bool bridge_add_port(char *interface, char *port) +# +# Adds the port to the bridge +bridge_add_port() { + local iface="$1" port="$2" e + + interface_set_flag "${port}" promisc true + interface_up "${port}" + e=$( brctl addif "${iface}" "${port}" 2>&1 ) + if [[ -n ${e} ]]; then + interface_set_flag "${port}" promisc false + echo "${e}" >&2 + return 1 + fi + return 0 +} + +# bool bridge_delete_port(char *interface, char *port) +# +# Deletes a port from a bridge +bridge_delete_port() { + interface_set_flag "$2" promisc false + brctl delif "$1" "$2" +} + +# bool bridge_start(char *iface) +# +# set up bridge +# This can also be called by non-bridges so that the bridge can be created +# dynamically +bridge_pre_start() { + local iface="$1" ports briface i ifvar=$( bash_variable "$1" ) opts + eval ports=\"\$\{bridge_${ifvar}\[@\]\}\" + eval briface=\"\$\{bridge_add_${ifvar}\}\" + eval opts=\"\$\{brctl_${ifvar}\}\" + + [[ -z ${ports} && -z ${briface} && -z ${opts} ]] && return 0 + + # Destroy the bridge if it exists + [[ -n ${ports} ]] && bridge_stop "${iface}" + + # Allow ourselves to add to the bridge + if [[ -z ${ports} && -n ${briface} ]]; then + ports="${iface}" + iface="${briface}" + fi + + # Create the bridge if needed + bridge_exists "${iface}" || bridge_create "${iface}" + + if [[ -n ${ports} ]]; then + einfo "Adding ports to ${iface}" + eindent + + for i in ${ports}; do + interface_exists "${i}" && continue + eerror "interface ${i} does not exist" + return 1 + done + + for i in ${ports}; do + ebegin "${i}" + bridge_add_port "${iface}" "${i}" + eend $? || return 1 + done + eoutdent + fi + + return 0 +} + +# bool bridge_stop(char *iface) +# +# Removes the device +# returns 0 +bridge_stop() { + bridge_check_installed || return 0 + + local iface="$1" ports i deletebridge=false extra="" + + if bridge_exists "${iface}" ; then + ebegin "Destroying bridge ${iface}" + interface_down "${iface}" + ports=$( bridge_get_ports "${iface}" ) + deletebridge=true + eindent + else + # Work out if we're added to a bridge for removal or not + ports="${iface}" + iface=$( bridge_get_bridge "${iface}" ) + [[ -z ${iface} ]] && return 0 + extra=" from ${iface}" + fi + + for i in ${ports}; do + ebegin "Removing port ${i}${extra}" + bridge_delete_port "${iface}" "${i}" + eend $? + done + + if ${deletebridge} ; then + eoutdent + brctl delbr "${iface}" &>/dev/null + eend 0 + fi + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/dhclient b/net-scripts/net.modules.d/dhclient new file mode 100644 index 0000000..6d31321 --- /dev/null +++ b/net-scripts/net.modules.d/dhclient @@ -0,0 +1,196 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +dhclient() { + LC_ALL=C /sbin/dhclient "$@" +} + +# char* dhclient_provides(void) +# +# Returns a string to change module definition for starting up +dhclient_provides() { + echo "dhcp" +} + +# void dhclient_depend(void) +# +# Sets up the dependancies for the module +dhclient_depend() { + after interface +} + +# bool dhclient_check_installed(void) +# +# Returns 1 if dhclient is installed, otherwise 0 +dhclient_check_installed() { + [[ -x /sbin/dhclient ]] && return 0 + ${1:-false} && eerror "For DHCP (dhclient) support, emerge net-misc/dhcp" + return 1 +} + +# bool dhclient_check_depends(void) +# +# Checks to see if we have the needed functions +dhclient_check_depends() { + local f + + for f in interface_exists interface_get_address; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "dhclient: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# char* dhclient_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +dhclient_get_vars() { + echo "dhclient_$1 dhcp_$1" +} + +# bool dhclient_stop(char *iface) +# +# Stop dhclient on an interface +# Always returns 0 +dhclient_stop() { + local iface="$1" d + local pidfile="/var/run/dhclient-${iface}.pid" + + dhclient_check_installed || return 0 + [[ ! -f ${pidfile} ]] && return 0 + + # We check for a dhclient process first as if we attempt to release + # an interface for which dhclient has obtained an IP in the past + # it causes a "RELEASE" event anyway. + local pid=$( < "${pidfile}" ) + + local ifvar=$( bash_variable "${iface}" ) + eval d=\" \$\{dhcp_${ifvar}\} \" + [[ ${d} == " " ]] && d=" ${dhcp} " + + ebegin "Stopping dhclient on ${iface}" + if [[ ${d} == *" release "* ]]; then + local r=$( dhclient -q -r -pf "${pidfile}" \ + -sf "${MODULES_DIR}/helpers.d/dhclient-wrapper" "${iface}" ) + [[ ${r} == "deconfig" ]] + eend $? "dhclient returned a ${r}" + [[ -f "/var/cache/dhcp-${iface}.lease" ]] \ + && rm -f "/var/cache/dhcp-${iface}.lease" + else + kill -s TERM "${pid}" 2>/dev/null + clean_pidfile "${pidfile}" + eend 0 + fi + + return 0 +} + +# bool dhclient_start(char *iface) +# +# Start DHCP on an interface by calling dhclient $iface $options +# +# Returns 0 (true) when a DHCP address is obtained, otherwise 1 +dhclient_start() { + local iface="$1" opts ifvar=$( bash_variable "$1" ) + local pidfile="/var/run/dhclient-${iface}.pid" edit="" + local cffile="/etc/dhcp/dhclient.conf" + local d + + interface_exists "${iface}" true || return 1 + + eval edit=\"\$\{dhclient_edit_config_${ifvar}\}\" + [[ -z ${edit} ]] && eval edit="${dhclient_edit_config:-no}" + if [[ ${edit} == "yes" || ${edit} == "true" ]]; then + edit=true + else + edit=false + fi + + # Load our options + eval opts=\" \$\{dhclient_${ifvar}\} \" + + # Work out our cffile + x="${opts##* -cf }" + if [[ ${x} != "${opts}" ]]; then + x="${x%% *}" + if [[ -n ${x} ]]; then + cffile="${x}" + opts="${opts//-cf ${cffile}/}" + fi + fi + opts="${opts} -cf ${cffile}" + + # Ensure that the cffile does not contain any script lines + # as that will stop our helpers from running + if [[ -e ${cffile} ]] ; then + if grep -q "^[ \t]*script " "${cffile}" 2>/dev/null ; then + if ${edit} ; then + sed -i '/^[ \t]*script /d' "${cffile}" || return 1 + else + eerror "You have to remove the script parameter from ${cffile}" + return 1 + fi + fi + else + ${edit} && touch "${cffile}" 2>/dev/null + fi + + eval d=\" \$\{dhcp_${ifvar}\} \" + [[ ${d} == " " ]] && d=" ${dhcp} " + + # Send our hostname by editing cffile + if ${edit} && [[ -e ${cffile} && ${d} != *" nosendhost "* ]] ; then + local hostname=$( hostname ) + if [[ ${hostname} != "(none)" && ${hostname} != "localhost" ]]; then + sed -i '/^[ \t]*send[ \t]*host-name[ \t]*/d' "${cffile}" + if [[ -s ${cffile} ]]; then + sed -i '1 isend host-name "'"${hostname}"'";' "${cffile}" + else + echo "send host-name \"${hostname}\";" > "${cffile}" + fi + fi + fi + + # Bring up DHCP for this interface (or alias) + ebegin "Running dhclient" + + # Stop dhclient if it's already running + dhclient_stop "${iface}" + + if [[ ${background} == "yes" ]]; then + eval dhclient ${opts} -pf "${pidfile}" -q \ + -sf "${MODULES_DIR}/helpers.d/dhclient-wrapper" \ + "${iface}" &>/dev/null & + eend 0 + go_background + fi + + local x=$( eval dhclient ${opts} -1 -pf "${pidfile}" \ + -sf "${MODULES_DIR}/helpers.d/dhclient-wrapper" -q "${iface}" 2>&1 ) + # We just check the last 5 letters + [[ ${x:${#x} - 5:5} == "bound" ]] + if [[ $? != "0" ]]; then + echo "${x}" + # We need to kill the process if we fail + [[ -e ${pidfile} ]] && kill -s TERM $( < "${pidfile}" ) 2>/dev/null + eend 1 + return 1 + fi + eend 0 + + # DHCP succeeded, show address retrieved + local addr=$( interface_get_address "${iface}" ) + einfo "${iface} received address ${addr}" + + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/dhcpcd b/net-scripts/net.modules.d/dhcpcd new file mode 100644 index 0000000..25e3069 --- /dev/null +++ b/net-scripts/net.modules.d/dhcpcd @@ -0,0 +1,166 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +dhcpcd() { + LC_ALL=C /sbin/dhcpcd "$@" +} + +# char* dhcpcd_provides(void) +# +# Returns a string to change module definition for starting up +dhcpcd_provides() { + echo "dhcp" +} + +# void dhcpcd_depend(void) +# +# Sets up the dependancies for the module +dhcpcd_depend() { + after interface +} + +# bool dhcpcd_check_installed(void) +# +# Returns 1 if dhcpcd is installed, otherwise 0 +dhcpcd_check_installed() { + if [[ -x /sbin/dhcpcd ]]; then + if dhcpcd -h 2>&1 | grep -q "etcDir" ; then + return 0 + else + ${1:-false} && eerror "We require dhcpcd-1.3.22_p4-r12 or newer" + return 1 + fi + fi + + ${1:-false} && eerror "For DHCP (dhcpcd) support, emerge net-misc/dhcpcd" + return 1 +} + +# bool dhcpcd_check_depends(void) +# +# Checks to see if we have the needed functions +dhcpcd_check_depends() { + local f + + for f in interface_exists interface_get_address; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "dhcpcd: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# char* dhcpcd_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +dhcpcd_get_vars() { + echo "dhcpcd_$1 dhcp_$1" +} + +# bool dhcpcd_stop(char *iface) +# +# Stop DHCP on an interface by calling dhcpcd -z $iface +# +# Returns 0 (true) when a DHCP address dropped +# otherwise return 1 +dhcpcd_stop() { + local iface=$1 count signal pidfile="/var/run/dhcpcd-$1.pid" d + + dhcpcd_check_installed || return 0 + + [[ ! -f ${pidfile} ]] && return 0 + + ebegin "Stopping dhcpcd on ${iface}" + local pid=$( < "${pidfile}" ) + + local ifvar=$( bash_variable "${iface}" ) + eval d=\" \$\{dhcp_${ifvar}\} \" + [[ ${d} == " " ]] && d=" ${dhcp} " + + if [[ ${d} == *" release "* ]]; then + signal="HUP" + else + signal="TERM" + fi + + kill -s "${signal}" "${pid}" &>/dev/null + process_finished "${pid}" dhcpcd + eend $? "timed out" + return $? +} + +# bool dhcpcd_start(char *iface) +# +# Start DHCP on an interface by calling dhcpcd $iface $options +# +# Returns 0 (true) when a DHCP address is obtained, otherwise 1 +dhcpcd_start() { + local iface="$1" opts hostname pidfile="/var/run/dhcpcd-$1.pid" + local ifvar=$( bash_variable "${iface}" ) metric d + + interface_exists "${iface}" true || return 1 + + # Get our options + eval opts=\" \$\{dhcpcd_${ifvar}\} \" + + # Map some generic options to dhcpcd + eval d=\" \$\{dhcp_${ifvar}\} \" + [[ ${d} == " " ]] && d=" ${dhcp} " + [[ ${d} == *" nodns "* ]] && opts="${opts} -R" + [[ ${d} == *" nontp "* ]] && opts="${opts} -N" + [[ ${d} == *" nonis "* ]] && opts="${opts} -Y" + [[ ${d} == *" nogateway "* ]] && opts="${opts} -G" + + # We transmit the hostname by default + if [[ ${d} != *" nosendhost "* && ${opts} != *" -h "* ]]; then + hostname=$( hostname ) + [[ -n ${hostname} && ${hostname} != "(none)" \ + && ${hostname} != "localhost" ]] \ + && opts="-h \"${hostname}\" ${opts}" + fi + + # Stop dhcpcd from bringing the interface down when we exit + opts="${opts} -o" + + # Add our route metric + eval metric=\"\$\{metric_${ifvar}\}\" + [[ -n ${metric} ]] && opts="${opts} -m ${metric}" + + # Instruct dhcpcd to use our wrapper + opts="${opts} -c \"/lib/rcscripts/net.modules.d/helpers.d/dhcpcd-wrapper\"" + + # Instruct dhcpcd to create it's files in our state dir + opts="${opts} -e \"${statedir}/${iface}\"" + + # Bring up DHCP for this interface (or alias) + ebegin "Running dhcpcd" + + # Halt any existing dhcpcd process + dhcpcd_stop "${iface}" + + [[ ! -d "${statedir}/${iface}" ]] && mkdir -m 0755 -p "${statedir}/${iface}" + + if [[ ${background} == "yes" ]]; then + eval dhcpcd ${opts} ${iface} & + eend 0 + go_background + fi + + eval dhcpcd ${opts} ${iface} + eend $? || return 1 + + # DHCP succeeded, show address retrieved + local addr=$( interface_get_address "${iface}" ) + einfo "${iface} received address ${addr}" + + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/essidnet b/net-scripts/net.modules.d/essidnet new file mode 100644 index 0000000..967776b --- /dev/null +++ b/net-scripts/net.modules.d/essidnet @@ -0,0 +1,79 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to all the people in the Gentoo forums for their ideas and +# motivation for me to make this and keep on improving it + +# Load our config if it exists +[[ -f $(add_suffix "/etc/conf.d/wireless" ) ]] \ +&& source $(add_suffix "/etc/conf.d/wireless" ) + +# void essidnet_depend(void) +# +# Sets up the dependancies for the module +essidnet_depend() { + before interface + after wireless + installed wireless +} + +# bool essidnet_check_installed(void) +# +# Always returns 0 as we are "installed" by wireless in the depend function +essidnet_check_installed() { + return 0 +} + +# char* essidnet_provides(void) +# +# Returns a string to change module definition for starting up +essidnet_provides() { + echo "essidnet" +} + +# bool essidnet_check_depends(void) +# +# Checks to see if we have the needed functions +essidnet_check_depends() { + local f + + for f in wireless_check_extensions wireless_get_essid wireless_get_ap_mac_address; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "essidnet: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool essidnet_start(char *iface) +# +# All interfaces and module scripts expose modulename_get_vars +# which returns a space seperated list of user configuration variables +# We can override each variable here from a given ESSID or the MAC +# of the AP connected to. MAC configuration takes precedence +# Always returns 0 +essidnet_pre_start() { + local iface="$1" + + wireless_check_extensions "${iface}" || return 0 + + local mac=$( wireless_get_ap_mac_address "${iface}" ) + local ESSID=$( wireless_get_essid "${iface}" ) + local essid=$( bash_variable ${ESSID} ) + mac="${mac//:/}" + + vebegin "Configuring ${iface} for ESSID \"${ESSID//\\\\/\\\\}\"" 2>/dev/null + configure_variables "${iface}" "${essid}" "${mac}" + + # Backwards compat for old gateway var + eval x=\"\$\{gateway_${essid}\}\" + [[ -n ${x} ]] && gateway="${iface}/${x}" + + veend 0 2>/dev/null + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/helpers.d/dhclient-wrapper b/net-scripts/net.modules.d/helpers.d/dhclient-wrapper new file mode 100755 index 0000000..075229d --- /dev/null +++ b/net-scripts/net.modules.d/helpers.d/dhclient-wrapper @@ -0,0 +1,45 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Instead of writing new functions for dhclient, we simply map their variables +# over to udhcpc style ones and call those scripts! + +case "${reason}" in + BOUND|REBOOT|REBIND) action="bound" ;; + RENEW) action="renew" ;; + RELEASE|PREINIT|FAIL|EXPIRE|TIMEOUT) action="deconfig" ;; + MEDIUM) exit 0 ;; +esac + +if [[ -z ${action} ]]; then + echo "dhclient sent an unknown action ${reason}!" >&2 + exit 1 +fi + +export ip="${new_ip_address}" +export subnet="${new_subnet_mask}" +export broadcast="${new_broadcast_address}" +export routers="${new_routers}" + +export hostname="${new_host_name}" + +export dns_domain_${interface}="${new_domain_name}" +export dns_servers_${interface}="${new_domain_name_servers}" + +export ntp_servers_${interface}="${new_domain_name_servers}" + +export nis_domain_${interface}="${new_nis_domain}" +export nis_servers_${interface}="${new_nis_servers}" + +/lib/rcscripts/net.modules.d/helpers.d/dhcp "${action}" +result="$?" + +[[ -e /etc/dhcp/dhclient-exit-hooks ]] \ +&& ( . /etc/dhcp/dhclient-exit-hooks ) + +exit "${result}" + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/helpers.d/dhcp b/net-scripts/net.modules.d/helpers.d/dhcp new file mode 100755 index 0000000..3996c1a --- /dev/null +++ b/net-scripts/net.modules.d/helpers.d/dhcp @@ -0,0 +1,130 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +action="$1" +service="net.${interface}" + +. /lib/rcscripts/net.modules.d/helpers.d/module-loader + +# Bring the interface up +interface_is_up "${interface}" || interface_up "${interface}" + +case "${action}" in + bound|renew) + # We handle these actions below + ;; + deconfig) + # Just remove IPv4 / inet addresses + interface_del_addresses "${interface}" true + if service_starting "${service}" || service_started "${service}" ; then + mark_service_inactive "net.${interface}" + fi + remove_state "${interface}" + if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then + best_interface=$( select_best_interface ) + apply_state "${best_interface}" + fi + echo "${action}" + exit 0 + ;; + nak) + echo "${action}" + exit 0 + ;; + leasefail) + if service_starting "${service}" || service_started "${service}" ; then + mark_service_inactive "net.${interface}" + fi + echo "${action}" + exit 0 + ;; + *) + echo "${action}" + echo "We don't handle that action" >&2 + exit 1 + ;; +esac + +# Map MAC address variables to interface variables +macnet_pre_start "${interface}" 1>/dev/null + +# Map wireless ESSID variables to interface variables +if [[ -n ${wireless_module} ]]; then + if wireless_check_extensions "${interface}" ; then + essidnet_pre_start "${interface}" 1>/dev/null + fi +fi + +# Calculate the metric for our routes +ifvar=$( bash_variable "${interface}" ) +eval metric=\"\$\{metric_${ifvar}\}\" +if [[ -z ${metric} ]]; then + if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then + metric=$( calculate_metric "${interface}" ) + else + metric="0" + fi + eval metric_${ifvar}="${metric}" +fi + + +eval d=\" \$\{dhcp_${ifvar}\} \" +[[ ${d} == " " ]] && d=" ${dhcp} " + +# Configure our IP address +ip="${ip// }" +subnet="${subnet// }" +cidr=$( netmask2cidr "${subnet}" ) +broadcast="${broadcast// }" +[[ -n ${broadcast} ]] && broadcast="broadcast ${broadcast}" + +# If we don't have our address then we flush it and then add our new one +curip=$( interface_get_address "${interface}" ) +if [[ ${curip} != "${ip}/${cidr}" ]] ; then + # Just remove IPv4 / inet addresses + interface_del_addresses "${interface}" true + interface_add_address "${interface}" "${ip}/${cidr}" "${broadcast}" +fi + +# Store the address in a cache for future usage +echo "${ip}" > "/var/cache/dhcp-${interface}.lease" +chmod 600 "/var/cache/dhcp-${interface}.lease" + +# Configure our default route - we only have 1 default route +if [[ ${d} != *" nogateway "* ]]; then + for r in ${routers}; do + interface_default_route "${interface}" "${r}" "${metric:-0}" && break + done +fi + +# Configure our hostname - but only if we need it +if [[ -n ${hostname} ]]; then + x=$( /bin/hostname ) + [[ ${x} == "(none)" || ${x} == "localhost" ]] && /bin/hostname "${hostname}" +fi + +[[ ! -d "${statedir}/${interface}" ]] \ +&& mkdir -m 0755 -p "${statedir}/${interface}" + +# Only setup the information we're told to +# By default that's everything +[[ ${d} != *" nodns "* ]] && system_dns "${interface}" +[[ ${d} != *" nontp "* ]] && system_ntp "${interface}" +[[ ${d} != *" nonis "* ]] && system_nis "${interface}" + +if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then + best_interface=$( select_best_interface ) + apply_state "${best_interface}" +else + apply_state "${interface}" +fi + +! service_stopping "${service}" && mark_service_started "${service}" + +echo "${action}" +exit 0 + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/helpers.d/dhcp-state b/net-scripts/net.modules.d/helpers.d/dhcp-state new file mode 100644 index 0000000..8bc2681 --- /dev/null +++ b/net-scripts/net.modules.d/helpers.d/dhcp-state @@ -0,0 +1,31 @@ +#!/bin/bash +# Copyright (c) 2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +MODULES_DIR="/lib/rcscripts/net.modules.d" +. /lib/rcscripts/sh/rc-services.sh +. "${MODULES_DIR}/helpers.d/functions" +conf=$(add_suffix "/etc/conf.d/net") +[[ -e ${conf} ]] && source "${conf}" + +service="net.${interface}" + +if [[ ${action} != "up" ]]; then + if service_starting "${service}" || service_started "${service}" ; then + mark_service_inactive "${service}" + fi + remove_state "${interface}" false +else + ! service_stopping "${service}" && mark_service_started "${service}" +fi + +if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then + best_interface=$( select_best_interface ) + apply_state "${best_interface}" +elif [[ ${action} == "up" ]]; then + apply_state "${interface}" +fi + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/helpers.d/dhcpcd-wrapper b/net-scripts/net.modules.d/helpers.d/dhcpcd-wrapper new file mode 100755 index 0000000..9768535 --- /dev/null +++ b/net-scripts/net.modules.d/helpers.d/dhcpcd-wrapper @@ -0,0 +1,51 @@ +#!/bin/bash +# Copyright (c) 2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +interface="${1##*/dhcpcd-}" +interface="${interface%%.info}" + +if [[ $2 != "up" && $2 != "new" ]]; then + action="down" +else + action="up" +fi + +. /lib/rcscripts/net.modules.d/helpers.d/module-loader + +if [[ ${action} == "up" ]]; then + # Map MAC address variables to interface variables + macnet_pre_start "${interface}" 1>/dev/null + + # Map wireless ESSID variables to interface variables + if [[ -n ${wireless_module} ]]; then + if wireless_check_extensions "${interface}" ; then + essidnet_pre_start "${interface}" 1>/dev/null + fi + fi + + # Add any search paths if we have any defined + ifvar=$( bash_variable "${interface}" ) + eval d=\" \$\{dhcp_${ifvar}\} \" + [[ ${d} == " " ]] && d=" ${dhcp} " + + resolv="${statedir}/${interface}/resolv.conf" + + if [[ ${d} != *" nodns "* ]]; then + eval search=\"\$\{dns_search_${ifvar}\}\" + if [[ -n ${search} ]]; then + tmp="${revolv}.$$" + egrep -v "^[ \t]*(search|domain)[ \t]*" "${resolv}" > "${tmp}" + echo "search ${search}" >> "${tmp}" + mv "${tmp}" "${resolv}" + fi + fi + + system_dns_extra "${interface}" "${resolv}" +fi + +. /lib/rcscripts/net.modules.d/helpers.d/dhcp-state + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/helpers.d/functions b/net-scripts/net.modules.d/helpers.d/functions new file mode 100644 index 0000000..5f80d34 --- /dev/null +++ b/net-scripts/net.modules.d/helpers.d/functions @@ -0,0 +1,577 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# We will be loaded after conf.d/rc and conf.d/net so we can set a default +# here. +RC_AUTO_INTERFACE="${RC_AUTO_INTERFACE:-no}" + +netdir="/var/lib/net-scripts" +statedir="${netdir}/state" + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* interface_device(char *iface) +# +# Gets the base device of the interface +# Can handle eth0:1 and eth0.1 +# Which returns eth0 in this case +interface_device() { + local dev="${1%%.*}" + [[ ${dev} == "$1" ]] && dev="${1%%:*}" + echo "${dev}" +} + +# char* interface_type(char* iface) +# +# Returns the base type of the interface +# eth, ippp, etc +interface_type() { + echo "${1%%[0-9]*}" +} + +# void save_state(char *interface) +# +# Saves state information regarding the interface +save_state() { + local iface="$1" + local d="${statedir}/${iface}" + + [[ ! -d ${d} ]] && mkdir -m 0755 -p "${d}" + cp -a /etc/resolv.conf /etc/ntp.conf /etc/yp.conf "${d}" 2>/dev/null +} + +# void remove_state(char *interface) +# +# Removes state information regarding the interface +remove_state() { + local d="${statedir}/$1" + + [[ -d ${d} ]] && rm -Rf "${d}" 2>/dev/null + [[ ! ${2:-true} ]] && mkdir -m 0755 -p "${d}" +} + +# void apply_state(char *interface) +# +# Apply's state information about the interface to the system +# If the files in the state dir are not links back to etc then +# we create them if RC_AUTO_INTERFACE="yes" +# +apply_state() { + local iface="$1" + + if [[ -z ${iface} ]]; then + iface=$( select_best_interface ) + [[ -z ${iface} ]] && return + fi + + local d="${statedir}/${iface}" + if [[ -d ${d} ]]; then + local files=$( ls "${d}" ) + if [[ -n ${files} ]] ; then + if [[ ${RC_AUTO_INTERFACE} == "yes" ]]; then + cp -aR "${d}"/* "${netdir}" + local file + for file in ${files} ; do + # Skip .sv files + [[ ${file} == *".sv" ]] && contine + local link=$( readlink "/etc/${file}" 2>/dev/null ) + if [[ ${link} != "${netdir}/${file}" ]]; then + [[ -e "/etc/${file}" ]] && rm -f "/etc/${file}" + ln -snf "${netdir}/${file}" "/etc/${file}" + fi + done + else + cp -ar "${d}"/* /etc + fi + fi + fi + + [[ ${RC_AUTO_INTERFACE} == "yes" ]] && merge_configs +} + +# char* order_interfaces(bool require_gateway) +# +# Lists the interfaces in route metric order that we have configured +# (ie a state dir exists) +# require_gateway defaults to false +order_interfaces() { + local ifaces + + if [[ ${1:-false} == "true" ]]; then + ifaces=$(awk '$2!="Gateway" { print $7, $1 }' /proc/net/route \ + | sort -n | cut -d' ' -f2 | uniq) + else + ifaces=$(awk '$2=="00000000" { print $7, $1 }' /proc/net/route \ + | sort -n | cut -d' ' -f2 ) + fi + + # Append lo if it's up + if grep -q "^lo[ \t]*" /proc/net/route ; then + ifaces="${ifaces} lo" + fi + + local i order + for i in ${ifaces}; do + [[ -d "${statedir}/${i}" ]] && order="${order}${i} " + done + + echo "${order}" +} + +# void merge_resolv() +# +# Merges the resolv.conf info from active interfaces +merge_resolv() { + local -a ifaces=( $(order_interfaces) ) + local i j f + + # We only work for ifaces with a resolv.conf + j=${#ifaces[@]} + for (( i=0; i<j; i++ )); do + [[ ! -e "${statedir}/${ifaces[i]}/resolv.conf" ]] && unset ifaces[i] + done + ifaces=( "${ifaces[@]}" ) + + # No point merging unless there are two or more interfaces + [[ ${#ifaces[@]} -lt 2 ]] && return + + veinfo "Merging resolv.conf from interfaces ${ifaces[@]}" + + local -a search srvs opts sortlist + j=0 + for (( i=0; i<${#ifaces[@]}; i++ )); do + f="${statedir}/${ifaces[i]}/resolv.conf" + srvs[i]=$( sed -n -e 's/^[ \t]*nameserver[ \t]*\([^#]*\).*/\1/p' "${f}" \ + | sed 2q ) + + search[i]=$( sed -n -e 's/^[ \t]*\(domain\|search\)[ \t]*\([^#]*\).*/\2/p' \ + "${f}" | sed -e '$!d' ) + + opts[i]=$( sed -n -e 's/^[ \t]*options[ \t]*\([^#]*\).*/\1#/p;' "${f}" | xargs ) + sortlist[i]=$( sed -n -e 's/^[ \t]*sortlist[ \t]*\([^#]*\).*/\1/p' "${f}" ) + + if [[ -z ${srvs[i]} && -z ${opts[i]} && -z ${sortlist[i]} ]]; then + unset srvs[i] + unset search[i] + unset opts[i] + unset sortlist[i] + continue + fi + + # No point in handling more than 3 interfaces due to libc limits + (( j++ )) + [[ ${j} -gt 2 ]] && break + done + srvs=( "${srvs[@]}" ) + search=( ${search[@]} ) + opts=( "${opts[@]}" ) + sortlist=( ${sortlist[@]} ) + + local new_srvs + j=0 + # Add interface primary nameservers + for (( i=0;i<${#srvs[@]}; i++ )); do + local -a n=( ${srvs[i]} ) + if [[ " ${new_srvs} " != *" ${n[0]} "* ]]; then + new_srvs="${new_srvs} ${n[0]}" + # libc can only handle 3 name servers + (( j++ )) + [[ ${j} -gt 2 ]] && break + fi + done + + # Add interface secondary nameservers + if [[ ${j} -lt 3 ]]; then + for (( i=0;i<${#srvs[@]}; i++ )); do + local -a n=( ${srvs[i]} ) + [[ -z ${n[1]} ]] && continue + if [[ " ${new_srvs} " != *" ${n[1]} "* ]]; then + new_srvs="${new_srvs} ${n[1]}" + # libc can only handle 3 name servers + (( j++ )) + [[ ${j} -gt 2 ]] && break + fi + done + fi + + local new_search n_search=0 + for i in ${search[@]}; do + if [[ " ${new_search} " != *" ${i} "* ]]; then + new_search="${new_search} ${i}" + # libc limits us to 6 search domains + (( n_search++ )) + [[ ${n_search} -gt 5 ]] && break + fi + done + + local new_opts + for i in "${opts[@]}"; do + new_opts="${new_opts}#${i}" + done + + # Remove duplicate options + new_opts=$( + echo -e "${new_opts//\#/\n}" \ + | sort -u | sed -e 's/^/#/g' | xargs + ) + + local new_sortlist n_sortlist=0 + for i in ${sortlist[@]}; do + if [[ " ${new_sortlist} " != *" ${i} "* ]]; then + new_sortlist="${new_sortlist} ${i}" + # libc limits us to 10 items + (( n_sortlist++ )) + [[ ${n_sortlist} -gt 9 ]] && break + fi + done + + # Now we create a new resolv.conf to use + local f="${netdir}/resolv.conf.$$" + echo "# Generated by net-scripts from interfaces ${ifaces[@]}" > "${f}" + chmod 644 "${f}" + for i in ${new_srvs[@]}; do + echo "nameserver ${i}" >> "${f}" + done + if [[ -n ${new_search} ]]; then + if [[ ${n_search} == "1" ]]; then + echo "domain${new_search}" >> "${f}" + else + echo "search${new_search}" >> "${f}" + fi + fi + + [[ -n ${new_sortlist} ]] && echo "sortlist${new_sortlist}" >> "${f}" + + # We seperated the options out using # in our sed call above + # so we set IFS here. If you do any spliting futher down in this function + # then you will need to reset IFS. + local IFS="#" + for i in ${new_opts}; do + [[ -n ${i# } ]] && echo "options ${i# }" >> "${f}" + done + + mv "${f}" "${netdir}/resolv.conf" +} + + +# void merge_ntp() +# +# Merges the ntp.conf info from active interfaces +merge_ntp() { + local -a ifaces=( $(order_interfaces) ) + local i j f + + # We only work for ifaces with a ntp.conf + j=${#ifaces[@]} + for (( i=0; i<j; i++ )); do + [[ ! -e "${statedir}/${ifaces[i]}/ntp.conf" ]] && unset ifaces[i] + done + ifaces=( "${ifaces[@]}" ) + + # No point merging unless there are two or more interfaces + [[ ${#ifaces[@]} -lt 2 ]] && return + + veinfo "Merging ntp.conf from interfaces ${ifaces[@]}" + + local srvs + for (( i=0; i<${#ifaces[@]}; i++ )); do + f="${statedir}/${ifaces[i]}/ntp.conf" + srvs="${srvs} $( sed -n -e 's/^[ \t]*server[ \t]*\([^#]\)/\1/p' "${f}" )" + done + + # ntp does it's own preference list, so we just remove duplicates + sort_unique() { + set -- " ${@/%/\n}" + echo -e "$@" | sort -u + } + + srvs=$( sort_unique ${srvs} ) + + f="${netdir}/ntp.conf.$$" + echo "# Generated by net-scripts for interfaces ${ifaces[@]}" > "${f}" + chmod 644 "${f}" + + echo "restrict default noquery notrust nomodify" >> "${f}" + echo "restrict 127.0.0.1" >> "${f}" + + for i in ${srvs}; do + echo "restrict ${i} nomodify notrap noquery" >> "${f}" + echo "server ${i}" >> "${f}" + done + + echo "driftfile /var/lib/ntp/ntp.drift" >> "${f}" + echo "logfile /var/log/ntp.log" >> "${f}" + + mv "${f}" "${netdir}/ntp.conf" +} + +# void merge_configs() +# +# Merge config files together +merge_configs() { + merge_resolv + merge_ntp +} + +# char* select_best_interface() +# +# Selects the best interface to apply state information to +# This is currently based on routing metrics +select_best_interface() { + local -a ifs=( $(order_interfaces true) ) + + # Move lo to the back of the pecking order of it's active + local x=" ${ifs[@]} " + [[ ${x// lo / } != "${x}" ]] && ifs=( ${x// lo / } lo ) + + local iface + for iface in ${ifs[@]} ; do + if [[ -e "${statedir}/${iface}/resolv.conf" ]]; then + echo "${iface}" + return 0 + fi + done + + echo "${ifs[0]}" +} + +# int calculate_metric(char *interface) +# +# Calculates the best metric for the interface +# The Linux kernel does not use this at the moment, but we use it so that +# default routes remain and we can work out the "best" interface +calculate_metric() { + local iface="$1" exclude='$1!="Iface" && $1!="lo"' + + # Have we already got a metric? + local m=$( awk '$1=="'${iface}'" && $2=="00000000" { print $7 }' \ + /proc/net/route ) + if [[ -n ${m} ]]; then + echo "${m}" + return 0 + fi + + local itype=$( interface_type "${iface}" ) x i + + # If we're not a wireless device then exclude wireless from the + # routing table so we stay < 1000 + if [[ -e /proc/net/wireless ]]; then + if ! grep -q "^[ \t]*${iface}:[ \t]" /proc/net/wireless ; then + local i=$( sed -n -e 's/^[ \t]*\(.*\):.*/\1/p' /proc/net/wireless ) + for x in ${i} ; do + exclude="${exclude} && "'$1'"!=\"${x}\"" + done + fi + fi + + # Exclude ppp and ippp as well + local ix="ppp|ippp" + [[ ${itype} == "ppp" ]] && ix="ippp" + [[ ${itype} == "ippp" ]] && ix="ppp" + i=$( sed -n -e 's/^[ ]*\('${ix}'[0-9]*\):.*$/\1/p' /proc/net/dev ) + for x in ${i} ; do + exclude="${exclude} && "'$1'"!=\"${x}\"" + done + + local m=$( awk "${exclude} { print "'$7'" }" /proc/net/route \ + | sort -rn | head -n 1 | cut -d' ' -f2 ) + m="${m:--1}" + (( m ++ )) + + # If we're a wireless device then add 1000 so that wired interfaces take preference + if [[ -e /proc/net/wireless ]]; then + grep -q "^[ \t]*${iface}:[ \t]" /proc/net/wireless && (( m+= 1000 )) + fi + + # If we're a ppp device then we add 2000 for ISDN, otherwise 3000 + [[ ${itype} == "ippp" ]] && (( m+= 2000 )) + [[ ${itype} == "ppp" ]] && (( m+= 3000 )) + + echo "${m}" +} + +# int netmask2cidr(char *netmask) +# +# Returns the CIDR of a given netmask +netmask2cidr() { + local binary="" i bin + + for i in ${1//./ }; do + bin="" + while [[ ${i} != "0" ]]; do + bin=$[${i}%2]${bin} + (( i=i>>1 )) + done + binary="${binary}${bin}" + done + binary="${binary%%0*}" + echo "${#binary}" +} + +# char* netmask2cidr(int cidr) +# +# Returns the netmask of a given CIDR +cidr2netmask() { + local cidr="$1" netmask="" done=0 i sum=0 cur=128 + local octets frac + + (( octets=cidr/8 )) + (( frac=cidr%8 )) + while [[ octets -gt 0 ]]; do + netmask="${netmask}.255" + (( octets-- )) + (( done++ )) + done + + if [[ ${done} -lt 4 ]]; then + for (( i=0; i<${frac}; i++ )); do + (( sum+=cur )) + (( cur/=2 )) + done + netmask="${netmask}.${sum}" + (( done++ )) + + while [[ ${done} -lt 4 ]]; do + netmask="${netmask}.0" + (( done++ )) + done + fi + + echo "${netmask:1}" +} + +# char* ip_network(char *ip, char *netmask) +# +# Returns the network of the ip address +# ip can be 192.168.0.51/24 +# or +# ip can be 192.168.0.51 and netmask is 255.255.255.0 +ip_network() { + local ip="$1" mask="$2" i network x + + # We only work for IPv4 addresses + [[ ${ip} != *.*.*.* ]] && return + + # If we didn't get parameter 2 then assume we have a CIDR + if [[ -z ${mask} ]]; then + mask="${ip##*/}" + [[ -z ${mask} || ${mask} == ${ip} ]] && return 1 + mask=$( cidr2netmask "${mask}" ) + ip="${ip%%/*}" + fi + + ip=( ${ip//./ } ) + mask=( ${mask//./ } ) + + for (( i=0; i<4; i++ )); do + (( x=ip[i] & mask[i] )) + network="${network}${x}" + [[ ${i} -lt 3 ]] && network="${network}." + done + + echo "${network}" +} + +# bool clean_pidfile(char *file) +# +# Removes the given pidfile if the process is not running +# Returns 1 if the process is still running otherwise 0 +clean_pidfile() { + local pidfile="$1" + + [[ ! -f ${pidfile} ]] && return 0 + local pid=$( < "${pidfile}" ) + + if [[ -n ${pid} ]]; then + local cmd="${pidfile##*/}" + cmd="${cmd%%-*}" + ps -p "${pid}" 2>/dev/null | grep -q "${cmd}" && return 1 + fi + + rm -f "${pidfile}" + return 0 +} + +# bool process_finished(int pid, char* cmd) +# +# We wait for 10 seconds until the command ${cmd} +# stops running on the process ${pid} +process_finished() { + local i pid="$1" cmd="$2" secs="${3:-9}" + + for (( i=0; i<secs; i++ )); do + ps -p "${pid}" 2>/dev/null | grep -q "${cmd}" || return 0 + sleep 1 + done + + return 1 +} + +# void function_wrap(char* source, char* target) +# +# wraps function calls - for example function_wrap(this, that) +# maps function names this_* to that_* +function_wrap() { + local i + + [[ $( type -t "${2}_provides" ) == "function" ]] && return + + for i in $( typeset -f | grep -o '^'"${1}"'_[^ ]*' ); do + eval "${2}${i#${1}}() { ${i} \"\$@\"; }" + done +} + +# char[] * expand_parameters(char *cmd) +# +# Returns an array after expanding parameters. For example +# "192.168.{1..3}.{1..3}/24 brd +" +# will return +# "192.168.1.1/24 brd +" +# "192.168.1.2/24 brd +" +# "192.168.1.3/24 brd +" +# "192.168.2.1/24 brd +" +# "192.168.2.2/24 brd +" +# "192.168.2.3/24 brd +" +# "192.168.3.1/24 brd +" +# "192.168.3.2/24 brd +" +# "192.168.3.3/24 brd +" +expand_parameters() { + local x="$( eval echo ${@// /_} )" + local -a a=( ${x} ) + + a=( "${a[@]/#/\"}" ) + a=( "${a[@]/%/\"}" ) + echo "${a[*]//_/ }" +} + +# void configure_variables(char *interface, char *option1, [char *option2]) +# +# Maps configuration options from <variable>_<option> to <variable>_<iface> +# option2 takes precedence over option1 +configure_variables() { + local iface="$1" option1="$2" option2="$3" + + local mod func x i + local -a ivars ovars1 ovars2 + local ifvar=$( bash_variable "${iface}" ) + + for mod in ${MODULES[@]}; do + func="${mod}_get_vars" + if [[ $( type -t ${func} ) == "function" ]]; then + ivars=( $( "${func}" "${ifvar}" ) ) + ovars1=( $( "${func}" "${option1}" ) ) + [[ -n ${option2} ]] && ovars2=( $( "${func}" "${option2}" ) ) + for ((i = 0; i<${#ivars[@]}; i++)); do + x="" + [[ -n ${ovars2[i]} ]] && eval x=( \"\$\{${ovars2[i]}\[@\]\}\" ) + [[ -z ${x} ]] && eval x=( \"\$\{${ovars1[i]}\[@\]\}\" ) + [[ -n ${x} ]] && eval "${ivars[i]}=( "\"\$\{x\[@\]\}\"" )" + done + fi + done + + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/helpers.d/module-loader b/net-scripts/net.modules.d/helpers.d/module-loader new file mode 100644 index 0000000..f4f5f95 --- /dev/null +++ b/net-scripts/net.modules.d/helpers.d/module-loader @@ -0,0 +1,47 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +[[ -z ${MODULES_DIR} ]] && MODULES_DIR="/lib/rcscripts/net.modules.d" +. "${MODULES_DIR}/system" +. /lib/rcscripts/sh/rc-services.sh +. "${MODULES_DIR}/helpers.d/functions" +conf=$(add_suffix "/etc/conf.d/net") +[[ -e ${conf} ]] && source "${conf}" + +# Guess which interface module to load - we prefer iproute2 +if [[ -x /sbin/ip ]]; then + interface_module="iproute2" +elif [[ -x /sbin/ifconfig ]]; then + interface_module="ifconfig" +else + echo "Can't find a known interface module" >&2 + exit 1 +fi + +# iwconfig is the best bet for wireless - we use wpa_supplicant +# only if we need to +if [[ -x /sbin/iwconfig ]]; then + wireless_module="iwconfig" +elif [[ -x /sbin/wpa_supplicant \ + && -S "/var/run/wpa_supplicant/${interface}" ]]; then + wireless_module="wpa_supplicant" +fi + +MODULES=( "system" ) + +# Load our modules +. "${MODULES_DIR}/${interface_module}" +function_wrap "${interface_module}" interface +. "${MODULES_DIR}/macnet" +. "${MODULES_DIR}/system" + +if [[ -n ${wireless_module} ]]; then + . "${MODULES_DIR}/${wireless_module}" + function_wrap "${wireless_module}" wireless + . "${MODULES_DIR}/essidnet" +fi + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/helpers.d/pump-wrapper b/net-scripts/net.modules.d/helpers.d/pump-wrapper new file mode 100755 index 0000000..1adf0bf --- /dev/null +++ b/net-scripts/net.modules.d/helpers.d/pump-wrapper @@ -0,0 +1,37 @@ +#!/bin/bash +# Copyright (c) 2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +[[ $1 == "renewal" ]] && exit 0 + +action="$1" +interface="$2" + +if [[ ${action} == "up" ]]; then + . /lib/rcscripts/net.modules.d/helpers.d/module-loader + + # Map MAC address variables to interface variables + macnet_pre_start "${interface}" 1>/dev/null + + # Map wireless ESSID variables to interface variables + if [[ -n ${wireless_module} ]]; then + if wireless_check_extensions "${interface}" ; then + essidnet_pre_start "${interface}" 1>/dev/null + fi + fi + + # Add any search paths if we have any defined + ifvar=$( bash_variable "${interface}" ) + eval d=\" \$\{dhcp_${ifvar}\} \" + [[ ${d} == " " ]] && d=" ${dhcp} " + + resolv="${statedir}/${interface}/resolv.conf" + + system_dns_extra "${interface}" "${resolv}" +fi + +. /lib/rcscripts/net.modules.d/helpers.d/dhcp-state + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/helpers.d/udhcpc-wrapper b/net-scripts/net.modules.d/helpers.d/udhcpc-wrapper new file mode 100755 index 0000000..feb01e6 --- /dev/null +++ b/net-scripts/net.modules.d/helpers.d/udhcpc-wrapper @@ -0,0 +1,20 @@ +#!/bin/sh +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Map the dns, ntp and nis info so our system module can apply the setup + +export dns_domain_${interface}="${domain}" +export dns_servers_${interface}="${dns}" +export routers="${router}" + +export ntp_servers_${interface}="${ntpsrv}" + +export nis_domain_${interface}="${nisdomain}" +export nis_servers_${interface}="${nissrv}" + +/lib/rcscripts/net.modules.d/helpers.d/dhcp "$@" + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/ifconfig b/net-scripts/net.modules.d/ifconfig new file mode 100644 index 0000000..9bc31f1 --- /dev/null +++ b/net-scripts/net.modules.d/ifconfig @@ -0,0 +1,445 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +ifconfig() { + LC_ALL=C /sbin/ifconfig "$@" +} + +ifconfig_tunnel() { + LC_ALL=C /sbin/iptunnel "$@" +} + +route() { + LC_ALL=C /sbin/route "$@" +} + +# void ifconfig_depend(void) +# +# Sets up the dependancies for the module +ifconfig_depend() { + after macnet wireless +} + +# bool ifconfig_check_installed(void) +# +# Returns 1 if ifconfig is installed, otherwise 0 +ifconfig_check_installed() { + [[ -x /sbin/ifconfig ]] && return 0 + ${1:-false} && eerror "For ifconfig support, emerge sys-apps/net-tools" + return 1 +} + +# char* ifconfig_provides(void) +# +# Returns a string to change module definition for starting up +ifconfig_provides() { + echo "interface" +} + +# char* ifconfig_module(void) +# +# Returns the module name +# This is needed by dhclient as we run different scripts +# based on the interface +ifconfig_module() { + echo "ifconfig" +} + +# bool ifconfig_check_depends(void) +# +# Checks to see if we have the needed functions +ifconfig_check_depends() { + return 0 +} + +# bool ifconfig_exists(char *interface, bool report) +# +# Returns 1 if the interface exists, otherwise 0 +ifconfig_exists() { + local e=$( ifconfig -a | grep -o "^$1" ) report="${2:-false}" + [[ -n ${e} ]] && return 0 + ${report} && eerror "$1 does not exist" + return 1 +} + +# void ifconfig_up(char *iface) +# +# provides a generic interface for bringing interfaces up +ifconfig_up() { + ifconfig "$1" up +} + +# void ifconfig_down(char *iface) +# +# provides a generic interface for bringing interfaces down +ifconfig_down() { + ifconfig "$1" down +} + +# bool ifconfig_is_up(char *iface, bool withaddress) +# +# Returns 0 if the interface is up, otherwise 1 +# If withaddress is true then the interface has to have an IPv4 address +# assigned as well +ifconfig_is_up() { + local check="\<UP\>" addr="${2:-false}" + ${addr} && check="\<inet addr:.*${check}" + ifconfig "$1" | grep -Eq "${check}" && return 0 + return 1 +} + +# void ifconfig_set_flag(char *iface, char *flag, bool enabled) +# +# Sets or disables the interface flag +ifconfig_set_flag() { + local iface="$1" flag="$2" enable="$3" + ${enable} || flag="-${flag}" + ifconfig "${iface}" "${flag}" +} + +# void ifconfig_get_address(char *interface) +# +# Fetch the address retrieved by DHCP. If successful, echoes the +# address on stdout, otherwise echoes nothing. +ifconfig_get_address() { + local -a x=( $( ifconfig "$1" \ + | sed -n -e 's/.*inet addr:\([^ ]*\).*Mask:\([^ ]*\).*/\1 \2/p' ) ) + x[1]=$( netmask2cidr "${x[1]}" ) + echo "${x[0]}/${x[1]}" +} + +# void ifconfig_get_mac_address(char *interface) +# +# Fetch the mac address assingned to the network card +ifconfig_get_mac_address() { + local mac=$( ifconfig "$1" | sed -n -e \ + 's/.*HWaddr[ \t]*\<\(..:..:..:..:..:..\)\>.*/\U\1/p' ) + [[ ${mac} != '00:00:00:00:00:00' \ + && ${mac} != '44:44:44:44:44:44' \ + && ${mac} != 'FF:FF:FF:FF:FF:FF' ]] \ + && echo "${mac}" +} + +# void ifconfig_set_mac_address(char *interface, char *mac) +# +# Assigned the mac address to the network card +ifconfig_set_mac_address() { + ifconfig "$1" hw ether "$2" +} + +# int ifconfig_set_name(char *interface, char *new_name) +# +# Renames the interface +# This will not work if the interface is setup! +ifconfig_set_name() { + [[ -z $2 ]] && return 1 + local current="$1" new="$2" + + local mac=$( ifconfig_get_mac_address "${current}" ) + if [[ -z ${mac} ]]; then + eerror "${iface} does not have a MAC address" + return 1 + fi + + /sbin/nameif "${new}" "${mac}" +} + +# void ifconfig_get_aliases_rev(char *interface) +# +# Fetch the list of aliases for an interface. +# Outputs a space-separated list on stdout, in reverse order, for +# example "eth0:2 eth0:1" +ifconfig_get_aliases_rev() { + ifconfig | grep -o "^$1:[0-9]* " | tac +} + +# bool ifconfig_del_addresses(char *interface, bool onlyinet) +# +# Remove addresses from interface. Returns 0 (true) if there +# were addresses to remove (whether successful or not). Returns 1 +# (false) if there were no addresses to remove. +# If onlyinet is true then we only delete IPv4 / inet addresses +ifconfig_del_addresses() { + local iface="$1" i onlyinet="${2:-false}" + # We don't remove addresses from aliases + [[ ${iface} == *:* ]] && return 0 + + # If the interface doesn't exist, don't try and delete + ifconfig_exists "${iface}" || return 0 + + # iproute2 can add many addresses to an iface unlike ifconfig ... + # iproute2 added addresses cause problems for ifconfig + # as we delete an address, a new one appears, so we have to + # keep polling + while ifconfig "${iface}" | grep -q -m1 -o 'inet addr:[^ ]*' ; do + ifconfig "${iface}" 0.0.0.0 || break + done + + # Remove IPv6 addresses + if ! ${onlyinet} ; then + for i in $( ifconfig "${iface}" \ + | sed -n -e 's/^.*inet6 addr: \([^ ]*\) Scope:[^L].*/\1/p' ) ; do + /sbin/ifconfig "${iface}" inet6 del "${i}" + done + fi + return 0 +} + +# char* ifconfig_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +ifconfig_get_vars() { + echo "config_$1 routes_$1 fallback_$1 metric_$1 ifconfig_$1 \ + ifconfig_fallback_$1 routes_$1 inet6_$1 iface_$1 alias_$1 \ + broadcast_$1 netmask_$1" + # The depreciated gateway var has to be handled by + # each module if needed +} + +# bool ifconfig_get_old_config(char *iface) +# +# Returns config and config_fallback for the given interface +ifconfig_get_old_config() { + local iface="$1" ifvar=$( bash_variable "$1" ) i inet6 + + eval config=( \"\$\{ifconfig_${ifvar}\[@\]\}\" ) + eval config_fallback=( \"\$\{ifconfig_fallback_${ifvar}\[@\]\}\" ) + eval inet6=( \"\$\{inet6_${ifvar}\[@\]\}\" ) + + # BACKWARD COMPATIBILITY: populate the config_IFACE array + # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0) + eval i=\"\$\{iface_${ifvar}\}\" + if [[ -n ${i} && -z ${config} ]]; then + # Make sure these get evaluated as arrays + local -a aliases broadcasts netmasks + + # Start with the primary interface + config=( "${i}" ) + + # ..then add aliases + eval aliases=( \$\{alias_${ifvar}\} ) + eval broadcasts=( \$\{broadcast_${ifvar}\} ) + eval netmasks=( \$\{netmask_${ifvar}\} ) + for (( i=0; i<${#aliases[@]}; i++ )); do + config[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}" + done + fi + + # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses + [[ ${#inet6[@]} == 1 && ${inet6} == *' '* ]] && inet6=( ${inet6} ) + + # Add inet6 addresses to our config if required + [[ -n ${inet6} ]] && config=( "${config[@]}" "${inet6[@]}" ) + + return 0 +} + +# bool ifconfig_iface_stop(char *interface) +# +# Do final shutdown for an interface or alias. +# +# Returns 0 (true) when successful, non-zero (false) on failure +ifconfig_iface_stop() { + # If an alias is already down, then "ifconfig eth0:1 down" + # will try to bring it up with an address of "down" which + # fails. Do some double-checking before returning error + # status + ifconfig_is_up "$1" || return 0 + ifconfig_down "$1" && return 0 + + # It is sometimes impossible to transition an alias from the + # UP state... particularly if the alias has no address. So + # ignore the failure, which should be okay since the entire + # interface will be shut down eventually. + [[ $1 == *:* ]] && return 0 + return 1 +} + +# bool ifconfig_pre_start(char *interface) +# +# Runs any pre_start stuff on our interface - just the MTU atm +# We set MTU twice as it may be needed for DHCP - a dhcp client could +# change it in error, so we set MTU in post start too +ifconfig_pre_start() { + local iface="$1" + + interface_exists "${iface}" || return 0 + + local ifvar=$( bash_variable "$1" ) mtu + + # MTU support + eval mtu=\"\$\{mtu_${ifvar}\}\" + [[ -n ${mtu} ]] && ifconfig "${iface}" mtu "${mtu}" + + return 0 +} + + +# bool ifconfig_post_start(char *iface) +# +# Bring up iface using ifconfig utilities, called from iface_start +# +# Returns 0 (true) when successful on the primary interface, non-zero +# (false) when the primary interface fails. Aliases are allowed to +# fail, the routine should still return success to indicate that +# net.eth0 was successful +ifconfig_post_start() { + local iface="$1" ifvar=$( bash_variable "$1" ) routes x metric mtu cidr + eval metric=\"\$\{metric_${ifvar}\}\" + + ifconfig_exists "${iface}" || return 0 + + # Make sure interface is marked UP + ifconfig_up "${iface}" + + # MTU support + eval mtu=\"\$\{mtu_${ifvar}\}\" + [[ -n ${mtu} ]] && ifconfig "${iface}" mtu "${mtu}" + + eval routes=( \"\$\{routes_${ifvar}\[@\]\}\" ) + + # BACKWARD COMPATIBILITY: set the default gateway + if [[ ${gateway} == "${iface}/"* ]]; then + # We don't add the old gateway if one has been set in routes_IFACE + local gw=true + for x in "${routes[@]}"; do + [[ ${x} != *"default gw"* ]] && continue + gw=false + break + done + ${gw} && routes=( "${routes[@]}" "default gw ${gateway#*/}" ) + fi + + [[ -z ${routes} ]] && return 0 + + # Add routes for this interface, might even include default gw + einfo "Adding routes" + eindent + for x in "${routes[@]}"; do + ebegin "${x}" + + # Support iproute2 style routes + x="${x//via/gw} " + x="${x//scope * / }" + + # Assume we're a net device unless told otherwise + [[ " ${x} " != *" -net "* && " ${x} " != *" -host "* ]] && x="-net ${x}" + + # Support adding IPv6 addresses easily + if [[ ${x} == *:* ]]; then + [[ ${x} != *"-A inet6"* ]] && x="-A inet6 ${x}" + x="${x// -net / }" + fi + + # Add a metric if we don't have one + [[ ${x} != *" metric "* ]] && x="${x} metric ${metric}" + + route add ${x} dev "${iface}" + eend $? + done + eoutdent + + return 0 +} + +# bool ifconfig_add_address(char *iface, char *options ...) +# +# Adds the given address to the interface +ifconfig_add_address() { + local iface="$1" i=0 r e + + ifconfig_exists "${iface}" true || return 1 + + # Extract the config + local -a config=( "$@" ) + config=( ${config[@]:1} ) + + if [[ ${config[0]} == *:* ]]; then + # Support IPv6 - nice and simple + config[0]="inet6 add ${config[0]}" + else + # IPv4 is tricky - ifconfig requires an aliased device + # for multiple addresses + if ifconfig "${iface}" | grep -Eq "\<inet addr:.*" ; then + # Get the last alias made for the interface and add 1 to it + i=$( ifconfig | tac | grep -m 1 -o "^${iface}:[0-9]*" \ + | sed -n -e 's/'"${iface}"'://p' ) + i="${i:-0}" + (( i++ )) + iface="${iface}:${i}" + fi + + # ifconfig doesn't like CIDR addresses + local ip="${config[0]%%/*}" cidr="${config[0]##*/}" netmask + if [[ -n ${cidr} && ${cidr} != "${ip}" ]]; then + netmask=$( cidr2netmask "${cidr}" ) + config[0]="${ip} netmask ${netmask}" + fi + + # Support iproute2 style config where possible + r="${config[@]}" + config=( ${r//brd +/} ) + config=( "${config[@]//brd/broadcast}" ) + config=( "${config[@]//peer/pointtopoint}" ) + fi + + # Ensure that the interface is up so we can add IPv6 addresses + interface_up "${iface}" + + # Some kernels like to apply lo with an address when they are brought up + if [[ ${iface} == "lo" && ${config[@]} == "127.0.0.1 netmask 255.0.0.0 broadcast 127.255.255.255" ]]; then + ifconfig "${iface}" 0.0.0.0 + fi + + ifconfig "${iface}" ${config[@]} + r="$?" + [[ ${r} != "0" ]] && return ${r} + + local metric ifvar=$( bash_variable "${iface}" ) + # Remove the newly added route and replace with our metric + eval metric=\"\$\{metric_${ifvar}\}\" + [[ ${metric} == "0" || ${RC_AUTO_INTERFACE} != "yes" ]] && return ${r} + + if [[ -z ${netmask} ]]; then + for (( i=1; i<${#config[@]}-1; i++ )); do + if [[ ${config[i]} == "netmask" ]]; then + netmask="${config[i+1]}" + cidr=$( netmask2cidr "${netmask}" ) + break + fi + done + [[ -z ${netmask} ]] && return ${r} + fi + + local network=$( ip_network "${ip}" "${netmask}" ) + + if route del -net "${network}/${cidr}" metric 0 dev "${iface}" \ + 2>/dev/null ; then + route add -net "${network}/${cidr}" metric "${metric}" dev "${iface}" + fi + + return ${r} +} + +# void ifconfig_default_route(char* interface, char* gateway_ip, int metric) +# +# Force default route to the specified gateway +ifconfig_default_route() { + local metric="${3:-0}" + + # Delete any existing default routes + while true ; do + route del default metric "${metric}" dev "$1" 2>/dev/null || break + done + + # Then we add our route + route add default gw "$2" metric "${metric}" dev "$1" +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/ifplugd b/net-scripts/net.modules.d/ifplugd new file mode 100644 index 0000000..21e4bfa --- /dev/null +++ b/net-scripts/net.modules.d/ifplugd @@ -0,0 +1,156 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* ifplugd_provides(void) +# +# Returns a string to change module definition for starting up +ifplugd_provides() { + echo "plug" +} + +# void ifplugd_depend(void) +# +# Sets up the dependancies for the module +ifplugd_depend() { + after macnet + before interface +} + +# bool ifplugd_check_installed(void) +# +# Returns 0 if ifplugd is installed, otherwise 1 +ifplugd_check_installed() { + if [[ ! -x /usr/sbin/ifplugd ]]; then + ${1:-false} && eerror "For ifplugd support, emerge sys-apps/ifplugd" + return 1 + fi + return 0 +} + +# bool ifplugd_check_depends(void) +# +# Checks to see if we have the needed functions +ifplugd_check_depends() { + local f + + for f in interface_exists interface_get_mac_address; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "ifplugd: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool ifplugd_pre_start(char *interface) +# +# Start ifplugd on an interface +ifplugd_pre_start() { + local iface="$1" ifvar=$( bash_variable "$1" ) timeout i opts + local pidfile="/var/run/ifplugd.${iface}.pid" + + # We don't start ifplugd if we're being called from the background + ${IN_BACKGROUND} && return 0 + + interface_exists "${iface}" || return 0 + + # ifplugd could have been started by the old init script + if [[ -e ${pidfile} ]]; then + vewarn "ifplugd is already running on ${iface}" + return 0 + fi + + # We need a valid MAC address + # It's a basic test to ensure it's not a virtual interface + local mac=$(interface_get_mac_address "${iface}") + if [[ -z ${mac} ]]; then + vewarn "ifplugd only works on interfaces with a valid MAC address" + return 0 + fi + + # We don't work on bridges + if [[ $(type -t bridge_exists) == "function" ]]; then + if bridge_exists "${iface}"; then + veinfo "netplug does not work on bridges" + return 0 + fi + fi + + # Do some options + eval opts=\" \$\{ifplugd_${ifvar}\} \" + + # We don't work on wirelesss interfaces + # Although ifplugd can, we prefer wpa_supplicant, unless explicitly told + # so via our options + if [[ ${opts} != *" -m wlan "* && ${opts} != *" --api-mode=wlan "* ]]; then + if [[ $(type -t wireless_check_extensions) == "function" ]]; then + if wireless_check_extensions "${iface}"; then + veinfo "ifplugd does not work on wireless interfaces" + return 0 + fi + fi + fi + + ebegin "Starting ifplugd on ${iface}" + + # We need the interface up for ifplugd to listen to netlink events + interface_up "${iface}" + + # Mark the us as inactive so ifplugd can restart us + mark_service_inactive "net.${iface}" + + # Start ifplugd + start-stop-daemon --start --exec /usr/sbin/ifplugd \ + --pidfile "${pidfile}" \ + -- ${opts} --iface="${iface}" + eend "$?" || return 1 + + eindent + + eval timeout=\"\$\{plug_timeout_${ifvar}\:-10}\" + if [[ ${timeout} == "0" ]]; then + ewarn "WARNING: infinite timeout set for ${iface} to come up" + elif [[ ${timeout} -lt 0 ]]; then + ewarn "WARNING: negative timeout set for ${iface}" + exit 0 + fi + + veinfo "Waiting for ${iface} to be marked as started" + + i=0 + while true ; do + if service_started "net.${iface}"; then + local addr=$( interface_get_address "${iface}" ) + einfo "${iface} configured with address ${addr}" + exit 0 + fi + sleep 1 + (( i++ )) + [[ ${i} == "${timeout}" || ${i} -gt "${timeout}" ]] && break + done + + eend 1 "Failed to configure ${iface} in the background" + exit 0 +} + +# bool ifplugd_post_stop(char *iface) +# +# Stops ifplugd on an interface +# Returns 0 (true) when successful, non-zero otherwise +ifplugd_post_stop() { + ${IN_BACKGROUND} && return 0 + local iface="$1" + local pidfile="/var/run/ifplugd.${iface}.pid" + + [[ ! -e ${pidfile} ]] && return 0 + + ebegin "Stopping ifplugd on ${iface}" + start-stop-daemon --stop --exec /usr/sbin/ifplugd \ + --pidfile "${pidfile}" + eend $? +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/ipppd b/net-scripts/net.modules.d/ipppd new file mode 100644 index 0000000..8f5fc37 --- /dev/null +++ b/net-scripts/net.modules.d/ipppd @@ -0,0 +1,103 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* ipppd_provides(void) +# +# Returns a string to change module definition for starting up +ipppd_provides() { + echo "isdn" +} + +# void ipppd_depend(void) +# +# Sets up the dependancies for the module +ipppd_depend() { + after macnet + before interface +} + +# bool ipppd_check_installed(void) +# +# Returns 1 if isnd4k-utils is installed, otherwise 0 +ipppd_check_installed() { + [[ -x /usr/sbin/ipppd ]] && return 0 + ${1:-false} && eerror "For ISDN (ipppd) support, emerge net-dialup/isdn4k-utils" + return 1 +} + +# bool ipppd_check_depends(void) +# +# Checks to see if we have the needed functions +ipppd_check_depends() { + local f + + for f in interface_exists interface_type clean_pidfile; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "ipppd: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool ipppd_start(char *iface) +# +# Start isdn on an interface +# +# Returns 0 (true) when successful, non-zero otherwise +ipppd_pre_start() { + local iface="$1" opts itype=$( interface_type "$1" ) + local pidfile="/var/run/ipppd-${iface}.pid" + + # Check that we are a valid isdn interface + [[ ${itype} != "ippp" && ${itype} != "isdn" ]] && return 0 + + # Check that the interface exists + interface_exists "${iface}" true || return 1 + + if ! clean_pidfile "${pidfile}" ; then + ewarn "ipppd is already running on ${iface}" + eend 0 + return 0 + fi + + local ifvar=$( bash_variable "${iface}" ) + # Might or might not be set in conf.d/net + eval opts=\"\$\{ipppd_${ifvar}\}\" + + einfo "Starting ipppd for ${iface}" + /usr/sbin/ipppd "${opts}" pidfile "${pidfile}" \ + file "/etc/ppp/options.${iface}" >/dev/null + eend $? || return $? + + return 0 +} + +# bool ipppd_stop(char *iface) +# +# Stop isdn on an interface +# Returns 0 (true) when successful, non-zero otherwise +ipppd_stop() { + local iface="$1" pidfile="/var/run/ipppd-$1.pid" + + ipppd_check_installed || return 0 + [[ ! -f ${pidfile} ]] && return 0 + + clean_pidfile "${pidfile}" && return 0 + local pid=$( < "${pidfile}" ) r=0 + + einfo "Stopping ipppd for ${iface}" + kill -s TERM "${pid}" + if ! process_finished "${pid}" ipppd 10 ; then + kill -s KILL "${pid}" + process_finished "${pid}" ipppd 10 || r=1 + fi + + eend ${r} + return ${r} +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/iproute2 b/net-scripts/net.modules.d/iproute2 new file mode 100644 index 0000000..d069550 --- /dev/null +++ b/net-scripts/net.modules.d/iproute2 @@ -0,0 +1,382 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +ip() { + LC_ALL=C /sbin/ip "$@" +} + +iproute2_tunnel() { + LC_ALL=C /sbin/ip tunnel "$@" +} + +# void iproute2_depend(void) +# +# Sets up the dependancies for the module +iproute2_depend() { + after macnet wireless +} + +# bool iproute2_check_installed(void) +# +# Returns 1 if iproute2 is installed, otherwise 0 +iproute2_check_installed() { + local report="${1:-false}" installed="0" + if [[ ! -x /sbin/ip ]]; then + installed="1" + ${report} && eerror "For iproute2 support, emerge sys-apps/iproute2" + fi + if [[ ! -e /proc/net/netlink ]]; then + installed="1" + ${report} && eerror "iproute2 requires NetLink enabled in the kernel" + fi + return "${installed}" +} + +# char* iproute2_provides(void) +# +# Returns a string to change module definition for starting up +iproute2_provides() { + echo "interface" +} + +# char* iproute2_module(void) +# +# Returns the module name +# This is needed by dhclient as we run different scripts +# based on the interface +iproute2_module() { + echo "iproute2" +} + +# bool iproute2_check_depends(void) +# +# Checks to see if we have the needed functions +iproute2_check_depends() { + local f + + for f in interface_device; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "iproute2: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool iproute2_exists(char *interface, bool report) +# +# Returns 1 if the interface exists, otherwise 0 +iproute2_exists() { + local e=$( ip addr show label "$1" ) report="${2:-false}" + [[ -n ${e} ]] && return 0 + + ${report} && eerror "$1 does not exist" + return 1 +} + +# void iproute2_up(char *interface) +# +# provides a generic interface for bringing interfaces up +iproute2_up() { + ip link set up dev "$1" +} + +# void iproute2_down(char *interface) +# +# provides a generic interface for bringing interfaces up +iproute2_down() { + ip link set down dev "$1" +} + +# bool ifproute2_is_up(char *iface, bool withaddress) +# +# Returns 0 if the interface is up, otherwise 1 +# If withaddress is true then the interface has to have an IPv4 address +# assigned as well +iproute2_is_up() { + local check="\<UP\>" addr="${2:-false}" + ${addr} && check="${check}.*inet " + ip addr show "$1" | grep -Eq "${check}" && return 0 + return 1 +} + +# void iproute2_set_flag(char *iface, char *flag, bool enabled) +# +# Sets or disables the interface flag +iproute2_set_flag() { + local enable="$3" opt="on" + ${enable} || opt="off" + ip link set "$1" "$2" "${opt}" +} + +# void iproute2_get_address(char *interface) +# +# Fetch the address retrieved by DHCP. If successful, echoes the +# address on stdout, otherwise echoes nothing. +iproute2_get_address() { + ip -family inet addr show "$1" \ + | sed -n -e 's/.*inet \([^ ]*\).*/\1/p' +} + +# void iproute2_get_mac_address(char *interface) +# +# Fetch the mac address assingned to the network card +iproute2_get_mac_address() { + local mac=$( ip link show "$1" | sed -n -e \ + 's/^.*\<\(..:..:..:..:..:..\)\>.*/\U\1/p' ) + [[ ${mac} != '00:00:00:00:00:00' \ + && ${mac} != '44:44:44:44:44:44' \ + && ${mac} != 'FF:FF:FF:FF:FF:FF' ]] \ + && echo "${mac}" +} + +# void iproute2_set_mac_address(char *interface, char *mac) +# +# Assigned the mac address to the network card +iproute2_set_mac_address() { + ip link set address "$2" dev "$1" +} + +# int iproute2_set_name(char *interface, char *new_name) +# +# Renames the interface +# This will not work if the interface is setup! +iproute2_set_name() { + ip link set name "$2" dev "$1" +} + +# void iproute2_get_aliases_rev(char *interface) +# +# Fetch the list of aliases for an interface. +# Outputs a space-separated list on stdout, in reverse order, for +# example "eth0:2 eth0:1" +iproute2_get_aliases_rev() { + local iface=$( interface_device "$1" ) + ip addr show dev "${iface}" | grep -o "${iface}:[0-9].*" | tac +} + +# bool iproute2_del_addresses(char *interface, bool onlyinet) +# +# Remove addresses from interface. +# If onlyinet is true, then we only remove IPv4 / inet addresses. +iproute2_del_addresses() { + local pre="" + ${2:-false} && pre="-f inet" + ip ${pre} addr flush label "$1" scope global &>/dev/null + ip ${pre} addr flush label "$1" scope host &>/dev/null + return 0 +} + +# char* iproute2_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +iproute2_get_vars() { + echo "config_$1 routes_$1 fallback_$1 metric_$1 ipaddr_$1 ipaddr_fallback_$1 iproute_$1 inet6_$1" +} + +# bool iproute2_get_old_config(char *iface) +# +# Returns config and config_fallback for the given interface +iproute2_get_old_config() { + local ifvar=$( bash_variable "$1" ) inet6 + + # iproute2-style config vars + eval config=( \"\$\{ipaddr_${ifvar}\[@\]\}\" ) + eval config_fallback=( \"\$\{ipaddr_fallback_${ifvar}\[@\]\}\" ) + eval inet6=( \"\$\{inet6_${ifvar}\[@\]\}\" ) + + # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses + [[ ${#inet6[@]} == "1" && ${inet6} == *" "* ]] && inet6=( ${inet6} ) + + # Add inet6 addresses to our config if required + [[ -n ${inet6} ]] && config=( "${config[@]}" "${inet6[@]}" ) + + # Support old style iface_xxx syntax + [[ -z ${config} && $(type -t ifconfig_get_old_config) == "function" ]] \ + && ifconfig_get_old_config "${iface}" + + return 0 +} + +# bool iproute2_iface_stop(char *interface) +# +# Do final shutdown for an interface or alias. +# +# Returns 0 (true) when successful, non-zero (false) on failure +iproute2_iface_stop() { + local label="$1" iface=$( interface_device "$1" ) + + # Shut down the link if this isn't an alias or vlan + if [[ ${label} == "${iface}" ]]; then + iproute2_down "${iface}" + return $? + fi + return 0 +} + +# bool iproute2_add_address(char *interface, char *options ...) +# +# Adds an the specified address to the interface +# returns 0 on success and non-zero on failure +iproute2_add_address() { + local iface="$1" x + + iproute2_exists "${iface}" true || return 1 + + # Extract the config + local -a config=( "$@" ) + config=( ${config[@]:1} ) + + # Convert an ifconfig line to iproute2 + local n="${#config[@]}" + for (( x=0; x<n; x++ )); do + case "${config[x]}" in + netmask) + config[0]="${config[0]}/$( netmask2cidr ${config[x+1]} )" + unset config[x] config[x+1] + ;; + mtu) + ip link set mtu "${config[x+1]}" dev "${iface}" + unset config[x] config[x+1] + ;; + esac + done + config=( "${config[@]//pointtopoint/peer}" ) + + # Always scope lo addresses as host unless specified otherwise + [[ ${iface} == "lo" && " ${config[@]} " != *" scope "* ]] \ + && config=( "${config[@]}" "scope host" ) + + # IPv4 specifics + if [[ ${config[@]} == *.*.*.* ]]; then + # Work out a broadcast if none supplied + [[ ${config[@]} != *" brd "* && ${config[@]} != *" broadcast "* ]] \ + && config=( "${config[@]}" "brd +" ) + fi + + # Ensure that the interface is up so we can add IPv6 addresses + interface_up "${iface}" + + # Some kernels like to apply lo with an address when they are brought up + if [[ ${iface} == "lo" \ + && ${config[@]} == "127.0.0.1/8 brd 127.255.255.255 scope host" ]]; then + ip addr del dev "${iface}" 127.0.0.1/8 2>/dev/null + fi + + ip addr add dev "${iface}" ${config[@]} + local r="$?" + [[ ${r} != "0" ]] && return "${r}" + + local metric ifvar=$( bash_variable "${iface}" ) + # Remove the newly added route and replace with our metric + eval metric=\"\$\{metric_${ifvar}\}\" + [[ ${metric} == "0" || ${RC_AUTO_INTERFACE} != "yes" ]] && return "${r}" + + local network=$( ip_network "${config[0]}" ) + [[ -z ${network} ]] && return "${r}" + + local cidr="${config[0]##*/}" + if ip route del "${network}/${cidr}" metric 0 dev "${iface}" \ + 2>/dev/null ; then + ip route add "${network}/${cidr}" metric "${metric}" dev "${iface}" + fi + + return "${r}" +} + +# bool iproute2_pre_start(char *interface) +# +# Runs any pre_start stuff on our interface - just the MTU atm +# We set MTU twice as it may be needed for DHCP - a dhcp client could +# change it in error, so we set MTU in post start too +iproute2_pre_start() { + local iface="$1" + + interface_exists "${iface}" || return 0 + + local ifvar=$( bash_variable "$1" ) mtu + + # MTU support + eval mtu=\"\$\{mtu_${ifvar}\}\" + [[ -n ${mtu} ]] && ip link set mtu "${mtu}" dev "${iface}" + + return 0 +} + +# bool iproute2_post_start(char *interface) +# +# Runs any post_start stuff on our interface and adds routes +# Always returns 0 +iproute2_post_start() { + local iface="$1" ifvar=$( bash_variable "$1" ) routes metric mtu x netmask + + iproute2_exists "${iface}" || return 0 + + # Make sure interface is marked UP + iproute2_up "${iface}" + + # MTU support + eval mtu=\"\$\{mtu_${ifvar}\}\" + [[ -n ${mtu} ]] && ip link set mtu "${mtu}" dev "${iface}" + + eval routes=( \"\$\{routes_${ifvar}\[@\]\}\" ) + eval metric=\"\$\{metric_${ifvar}\:-0}\" + + # Test for old style ipaddr variable + if [[ -z ${routes} ]]; then + eval routes=( \"\$\{iproute_${ifvar}\[@\]\}\" ) + fi + + [[ -z ${routes} ]] && return 0 + + # Set routes with ip route -- this might also include default route + einfo "Adding routes" + eindent + for x in "${routes[@]}"; do + ebegin "${x}" + + # Support net-tools routing too + x="${x//gw/via}" + x="${x//-A inet6}" + x="${x//-net}" + [[ " ${x} " == *" -host "* ]] && x="${x//-host} scope host" + + # Attempt to support net-tools route netmask option + netmask="${x##* netmask }" + if [[ -n ${netmask} && ${x} != "${netmask}" ]]; then + netmask="${netmask%% *}" + x="${x// netmask ${netmask} / }" + local -a a=( ${x} ) + a[0]="${a[0]}/$( netmask2cidr ${netmask} )" + x="${a[@]}" + fi + + # Add a metric if we don't have one + [[ " ${x} " != *" metric "* ]] && x="${x} metric ${metric}" + + ip route append ${x} dev "${iface}" + eend $? + done + eoutdent + + return 0 +} + +# void iproute2_default_route(char* interface, char* gateway_ip, int metric) +# +# Force default route to the specified gateway, optionally on +# the given interface +iproute2_default_route() { + local metric="${3:-0}" + + ip route change default via "$2" metric "${metric}" dev "$1" 2>/dev/null \ + || ip route append default via "$2" metric "${metric}" dev "$1" 2>/dev/null +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/iptunnel b/net-scripts/net.modules.d/iptunnel new file mode 100644 index 0000000..f547a99 --- /dev/null +++ b/net-scripts/net.modules.d/iptunnel @@ -0,0 +1,84 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* iptunnel_provides(void) +# +# Returns a string to change module definition for starting up +iptunnel_provides() { + echo "iptunnel" +} + +# void iptunnel_depend(void) +# +# Sets up the dependancies for the module +iptunnel_depend() { + after wireless + before interface +} + +# bool iptunnel_check_installed(void) +# +# Tunnelling is provided by the interface +iptunnel_check_installed() { + return 0 +} + +# bool iptunnel_check_depends(void) +# +# Checks to see if we have the needed functions +iptunnel_check_depends() { + local f + + for f in interface_exists interface_tunnel; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "iptunnel: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# char* iptunnel_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +iptunnel_get_vars() { + echo "iptunnel_$1" +} + +# bool iptunnel_pre_start(char *iface) +# +# Create the device, give it the right perms +iptunnel_pre_start() { + local iface="$1" opts ifvar=$( bash_variable "$1" ) + + # Get our options + eval opts=\"\$\{iptunnel_${ifvar}\}\" + [[ -z ${opts} ]] && return 0 + + ebegin "Creating tunnel ${iface}" + interface_tunnel add "${iface}" ${opts} + eend "$?" + return "$?" + +} + +# bool iptunnel_stop(char *iface) +# +# Removes the device +iptunnel_stop() { + local iface="$1" + + interface_exists "${iface}" || return 0 + [[ -z $( interface_tunnel show "${iface}" 2>/dev/null ) ]] && return 0 + + ebegin "Destroying tunnel ${iface}" + interface_tunnel del "${iface}" + eend "$?" + return "$?" +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/iwconfig b/net-scripts/net.modules.d/iwconfig new file mode 100644 index 0000000..fbe6432 --- /dev/null +++ b/net-scripts/net.modules.d/iwconfig @@ -0,0 +1,935 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to all the people in the Gentoo forums for their ideas and +# motivation for me to make this and keep on improving it + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +iwconfig() { + LC_ALL=C /sbin/iwconfig "$@" +} +iwgetid() { + LC_ALL=C /sbin/iwgetid "$@" +} +iwlist() { + LC_ALL=C /sbin/iwlist "$@" +} +iwpriv() { + LC_ALL=C /sbin/iwpriv "$@" +} + +# void iwconfig_depend(void) +# +# Sets up the dependancies for the module +iwconfig_depend() { + before interface +} + +# bool iwconfig_check_installed(void) +# +# Returns 1 if wireless-tools is installed, otherwise 0 +iwconfig_check_installed() { + local report=${1:-false} + [[ -x /sbin/iwconfig ]] && return 0 + ${report} && eerror "For Wireless (802.11) support, emerge net-wireless/wireless-tools" + + if [[ ! -e /proc/net/wireless ]]; then + installed="1" + if ${report} ; then + eerror "iwconfig requires wireless support" + eerror "(CONFIG_NET_WIRELESS=y) enabled in the kernel" + fi + fi + + return 1 +} + +# char* iwconfig_provides(void) +# +# Returns a string to change module definition for starting up +iwconfig_provides() { + echo "wireless" +} + +# bool iwconfig_check_depends(void) +# +# Checks to see if we have the needed functions +iwconfig_check_depends() { + local f + + for f in interface_up interface_down interface_exists; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "iwconfig: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool iwconfig_check_extensions(char *interface) +# +# Checks to see if wireless extensions are enabled on the interface +iwconfig_check_extensions() { + [[ ! -e /proc/net/wireless ]] && return 1 + grep -q "^[ \t]*$1:[ \t]" /proc/net/wireless +} + +# char* iwconfig_get_wep_status(char *interface) +# +# Echos a string showing whether WEP is enabled or disabled +# for the given interface +iwconfig_get_wep_status() { + local key=$( iwconfig "$1" | grep -i -o "Encryption key:[0-9,A-F]" ) + local mode status="disabled" + + if [[ -n ${key} ]]; then + status="enabled" + mode=" - $( iwconfig "$1" | sed -n -e 's/^.*Security mode:\(.*[^ ]\).*/\1/p' )" + fi + + echo "(WEP ${status}${mode})" +} + +# char* iwconfig_get_essid(char *iface) +# +# Gets the current ESSID of the iface +iwconfig_get_essid() { + local i essid + + for (( i=0; i<5; i++ )); do + essid=$( iwgetid "$1" 2>/dev/null | sed -n -e 's/^.*ESSID:"\(.*\)"$/\1/p' ) + if [[ -n ${essid} ]]; then + echo "${essid}" + return 0 + fi + sleep 1 + done + + return 1 +} + +# char* iwconfig_get_ap_mac_address(char *interface) +# +# Returns the MAC address of the Access Point +# the interface is connected to +iwconfig_get_ap_mac_address() { + iwgetid --ap "$1" | sed -n -e 's/^.*Cell: .*\<\(..:..:..:..:..:..\)\>.*/\U\1/p' +} + +# char* iwconfig_get_mode(char *interface) +# +# Returns the wireless mode in lower case +iwconfig_get_mode() { + iwgetid --mode "$1" | sed -n -e 's/^.*Mode:\(.*\)/\L\1/p' +} + +# char* iwconfig_get_type(char *interface) +# +# Returns the type of interface - the IEEE part +iwconfig_get_type() { + iwconfig "$1" | sed -n -e 's/^'"$1"' *\([^ ]* [^ ]*\).*/\1/p' +} + +# void iwconfig_report(char *interface) +# +# Output how our wireless interface has been configured +iwconfig_report() { + local iface="$1" essid mac m="to" + + essid=$( iwconfig_get_essid "${iface}" ) + + local wep_status=$( iwconfig_get_wep_status "${iface}" ) + local channel=$( iwgetid --channel "${iface}" 2>/dev/null | cut -d: -f2 ) + [[ -n ${channel} ]] && channel="on channel ${channel} " + + essid="${essid//\\\\/\\\\}" + local mode=$( iwconfig_get_mode "${iface}" ) + if [[ ${mode} == "master" ]]; then + m="as" + else + mac=$( iwconfig_get_ap_mac_address "${iface}" ) + [[ -n ${mac} ]] && mac=" at ${mac}" + fi + + eindent + einfo "${iface} connected ${m} \"${essid}\"${mac}" + einfo "in ${mode} mode ${channel}${wep_status}" + eoutdent +} + +# char* iwconfig_get_wep_key(char *mac_address) +# +# Returns the configured WEP key for the given mac address +# or the given ESSID. The mac address setting takes precendence +iwconfig_get_wep_key() { + local mac="$1" key + eval key=\"\${mac_key_${mac//:/}\}\" + [[ -z ${key} ]] && eval key=\"\${key_${ESSIDVAR}\}\" + echo "${key:-off}" +} + +# void iwconfig_user_config(char *iface) +# +# Applies the user configuration to the interface +iwconfig_user_config() { + local iface="$1" conf ifvar=$( bash_variable "$1" ) + + # Apply the user configuration + eval conf=\"\$\{iwconfig_${ifvar}\}\" + if [[ -n ${conf} ]]; then + if ! eval iwconfig "${iface}" ${conf} ; then + ewarn "${iface} does not support the following configuration commands" + ewarn " \"${conf}\"" + fi + fi + + eval conf=\"\$\{iwpriv_${ifvar}\}\" + if [[ -n ${conf} ]]; then + if ! eval iwpriv "${iface}" ${conf} ; then + ewarn "${iface} does not support the following private ioctls" + ewarn " \"${conf}\"" + fi + fi +} + +# bool iwconfig_setup_specific(char *iface) +# +# Sets up our wireless interface to operate in ad-hoc or master mode +iwconfig_setup_specific() { + local iface="$1" mode="$2" channel key dessid + local ifvar=$( bash_variable "$1" ) + + if [[ -z ${ESSID} ]]; then + eerror "${iface} requires an ESSID to be set to operate in ${mode} mode" + eerror "adjust the essid_${iface} setting in /etc/conf.d/wireless" + return 1 + fi + dessid="${ESSID//\\\\/\\\\}" + ESSIDVAR=$( bash_variable "${ESSID}" ) + key=$( iwconfig_get_wep_key ) + + if ! eval iwconfig "${iface}" key ${key} ; then + if [[ ${key} != "off" ]]; then + ewarn "${iface} does not support setting keys" + ewarn "or the parameter \"mac_key_${ESSIDVAR}\" or \"key_${ESSIDVAR}\" is incorrect" + fi + fi + + if ! iwconfig "${iface}" essid "${ESSID}" ; then + eerror "${iface} does not support setting ESSID to \"${dessid}\"" + return 1 + fi + iwconfig "${iface}" nick "${ESSID}" 2>/dev/null + + # We only change the mode if it's not the same + local cur_mode=$( iwconfig_get_mode "${iface}" ) + if [[ ${cur_mode} != "${mode}" ]]; then + if ! iwconfig "${iface}" mode "${mode}" ; then + eerror "${iface} does not support setting the mode to \"${mode}\"" + return 1 + fi + fi + + eval channel=\"\$\{channel_${ifvar}\}\" + # We default the channel to 3 + channel=${channel:-3} + + if ! iwconfig "${iface}" channel "${channel}" ; then + ewarn "${iface} does not support setting the channel to \"${channel}\"" + return 1 + fi + + iwconfig_user_config "${iface}" + iwconfig_report "${iface}" + + if ${IN_BACKGROUND}; then + mark_service_inactive "net.${iface}" + export IN_BACKGROUND + /etc/init.d/net.${iface} start & + exit 0 + fi + + return 0 +} + +# bool iwconfig_associate_mac(char *iface) +# +# Returns true if the AP MAC address is valid or not +iwconfig_associate_mac() { + # Checks if a MAC address has been assigned + local mac=$( iwconfig_get_ap_mac_address "$1" ) i + local -a invalid_macs=( + "00:00:00:00:00:00" + "44:44:44:44:44:44" + "FF:00:00:00:00:00" + "FF:FF:FF:FF:FF:FF" + ) + + [[ -z ${mac} ]] && return 1 + for i in "${invalid_macs[@]}"; do + [[ ${mac} == "${i}" ]] && return 1 + done + return 0 +} + +# bool iwconfig_associate_quality(char *iface) +# +# Returns true if the link quality is not 0 or 0. +iwconfig_associate_quality() { + local quality=$( \ + sed -n -e 's/^.*'"$1"': *[0-9]* *\([0-9]*\).*/\1/p' \ + /proc/net/wireless + ) + [[ ${quality} != "0" ]] + return "$?" +} + +# bool iwconfig_test_associated(char *iface) +# +# Returns true if the interface has associated with an Access Point +iwconfig_test_associated() { + local iface="$1" ttype ifvar=$( bash_variable "$1" ) + # Some drivers don't set MAC to a bogus value when assocation is lost/fails + # whereas they do set link quality to 0 + + ttype=$( eval echo \"\$\{associate_test_${ifvar}\:-mac}\" | tr '[:upper:]' '[:lower:]' ) + if [[ ${ttype} != "mac" && ${ttype} != "quality" && ${ttype} != "all" ]]; then + ewarn " associate_test_${iface} is not set to mac, quality or all" + ewarn " defaulting to \"mac\"" + test="mac" + fi + + case "${ttype}" in + mac) iwconfig_associate_mac "${iface}" && return 0 ;; + quality) iwconfig_associate_quality "${iface}" && return 0 ;; + all) iwconfig_associate_mac "${iface}" \ + && iwconfig_associate_quality "${iface}" && return 0 ;; + esac + + return 1 +} + +# bool iwconfig_wait_for_association(char *iface) +# +# Waits for a configured ammount of time until +# we are assocaited with an Access Point +iwconfig_wait_for_association() { + local iface="$1" i=0 timeout ifvar=$( bash_variable "$1" ) + eval timeout=\"\$\{associate_timeout_${ifvar}\}\" + [[ -z ${timeout} ]] && eval timeout=\"\$\{sleep_associate_${ifvar}\:-10\}\" + + [[ ${timeout} == "0" ]] \ + && vewarn "WARNING: infinite timeout set for association on ${iface}" + + while true; do + iwconfig_test_associated "${iface}" && return 0 + sleep 1 + [[ ${timeout} == "0" ]] && continue + (( i++ )) + [[ ${i} == "${timeout}" || ${i} -gt ${timeout} ]] && break + done + return 1 +} + +# bool iwconfig_associate(char *interface, char *mac_address, char *wep_required) +# +# Tries to associate the interface with an Access Point +# If we scanned the Access Point we know if we need WEP to associate or not +# and if we have a WEP key for the ESSID or not +# so we can fail gracefully without even trying to connect +iwconfig_associate() { + local iface="$1" mode="${2:-managed}" + local mac="$3" wep_required="$4" w="(WEP Disabled)" + local dessid="${ESSID//\\\\/\\\\}" key + wep_required="${wep_required:-off}" + + iwconfig "${iface}" mode "${mode}" 2>/dev/null + if [[ ${ESSID} == "any" ]]; then + iwconfig "${iface}" ap any 2>/dev/null + dessid="any" + unset ESSIDVAR + else + ESSIDVAR=$( bash_variable "${ESSID}" ) + key=$( iwconfig_get_wep_key "${mac}" ) + if [[ ${wep_required} == "yes" && ${key} == "off" ]]; then + vewarn "WEP key is not set for \"${dessid}\" - not connecting" + return 1 + fi + if [[ ${wep_required} == "no" && ${key} != "off" ]]; then + key="off" + vewarn "\"${dessid}\" is not WEP enabled - ignoring setting" + fi + + if ! eval iwconfig "${iface}" key ${key} ; then + if [[ ${key} != "off" ]]; then + ewarn "${iface} does not support setting keys" + ewarn "or the parameter \"mac_key_${ESSIDVAR}\" or \"key_${ESSIDVAR}\" is incorrect" + return 1 + fi + fi + [[ ${key} != "off" ]] && w=$( iwconfig_get_wep_status "${iface}" ) + fi + + if ! iwconfig "${iface}" essid "${ESSID}" ; then + if [[ ${ESSID} != "any" ]]; then + ewarn "${iface} does not support setting ESSID to \"${dessid}\"" + fi + fi + iwconfig "${iface}" nick "${ESSID}" 2>/dev/null + + vebegin "Connecting to \"${dessid}\" ${w}" + + if [[ ${ESSID} != "any" && $( type -t preassociate ) == "function" ]]; then + veinfo "Running preassociate function" + eindent + ( preassociate "${iface}" ) + e="$?" + eoutdent + if [[ ${e} != 0 ]]; then + veend 1 "preassociate \"${dessid}\" on ${iface} failed" + return 1 + fi + fi + + if ! iwconfig_wait_for_association "${iface}" ; then + veend 1 + return 1 + fi + veend 0 + + if [[ ${ESSID} == "any" ]]; then + ESSID=$( iwconfig_get_essid "${iface}" ) + iwconfig_associate "${iface}" + return $? + fi + + iwconfig_user_config "${iface}" + iwconfig_report "${iface}" + + if [[ $( type -t postassociate ) == "function" ]]; then + veinfo "Running postassociate function" + eindent + ( postassociate "${iface}" ) + eoutdent + fi + + if ${IN_BACKGROUND}; then + mark_service_started "net.${iface}" + mark_service_inactive "net.${iface}" + export IN_BACKGROUND + /etc/init.d/net.${iface} start & + exit 0 + fi + + return 0 +} + +# bool iwconfig_scan(char *iface) +# +# Fills 3 arrays with information from a wireless scan +iwconfig_scan() { + local iface="$1" mode x ifvar=$( bash_variable "$1" ) + + # First, we may need to change mode to scan in + mode=$( eval echo \"\$\{scan_mode_${ifvar}\}\" | tr '[:upper:]' '[:lower:]' ) + if [[ -n ${mode} ]]; then + if ! iwconfig "${iface}" mode "${mode}" ; then + ewarn "${iface} does not support setting the mode to \"${mode}\"" + fi + fi + + # Next we set any private driver ioctls needed + eval x=\"\$\{iwpriv_scan_pre_${ifvar}\}\" + if [[ -n ${x} ]]; then + if ! eval iwpriv "${iface}" ${x} ; then + ewarn "${iface} does not support the following private ioctls" \ + ewarn " \"${x}\"" + fi + fi + + # Set the essid to any. This is required for scanning + iwconfig "${iface}" essid any + + veinfo "Scanning for access points" + + # Sleep if required + eval x=\"\$\{sleep_scan_${ifvar}\}\" + [[ -n ${x} ]] && sleep "${x}" + + local error=true i=-1 line + local -a mac essid enc qual mode + + while read line; do + error=false + case "${line}" in + *Address:*) + (( i++ )) + mac[i]=$( echo "${line#*: }" | tr '[:lower:]' '[:upper:]' ) + ;; + *ESSID:*) + essid[i]="${line#*\"}" + essid[i]="${essid[i]%*\"}" + ;; + *Mode:*) + mode[i]=$(echo "${line#*:}" | tr '[:upper:]' '[:lower:]' ) + [[ ${mode[i]} == "master" ]] && mode[i]="managed" + ;; + *'Encryption key:'*) + enc[i]="${line#*:}" + ;; + *Quality*) + qual[i]="${line#*:}" + qual[i]="${qual[i]%/*}" + qual[i]="${qual[i]//[![:digit:]]/}" + qual[i]="${qual[i]:-0}" + ;; + esac + done < <( iwlist "${iface}" scan 2>/dev/null ) + + if ${error}; then + ewarn "${iface} does not support scanning" + eval x=\"\$\{adhoc_essid_${ifvar}\}\" + [[ -n ${x} ]] && return 0 + if [[ -n ${preferred_aps} ]]; then + [[ ${associate_order} == "forcepreferred" \ + || ${associate_order} == "forcepreferredonly" ]] && return 0 + fi + eerror "You either need to set a preferred_aps list in /etc/conf.d/wireless" + eerror " preferred_aps=( \"ESSID1\" \"ESSID2\" )" + eerror " and set associate_order_${iface}=\"forcepreferred\"" + eerror " or set associate_order_${iface}=\"forcepreferredonly\"" + eerror "or hardcode the ESSID to \"any\" and let the driver find an Access Point" + eerror " essid_${iface}=\"any\"" + eerror "or configure defaulting to Ad-Hoc when Managed fails" + eerror " adhoc_essid_${iface}=\"WLAN\"" + eerror "or hardcode the ESSID against the interface (not recommended)" + eerror " essid_${iface}=\"ESSID\"" + return 1 + fi + + # We may need to unset the previous private driver ioctls + eval x=\"\$\{iwpriv_scan_post_${ifvar}\}\" + if [[ -n ${x} ]]; then + if ! eval iwpriv "${iface}" ${x} ; then + ewarn "${iface} does not support the following private ioctls" \ + ewarn " \"${x}\"" + fi + fi + + # Change back mode if needed + x=$( eval echo \"\$\{mode_${ifvar}\:-managed}\" | tr '[:upper:]' '[:lower:]' ) + [[ ${mode} != "${x}" ]] && iwconfig "${iface}" mode "${x}" + + for (( i=0; i<${#mac[@]}; i++ )); do + # Don't like ad-hoc nodes by default + [[ ${mode[i]} == "ad-hoc" ]] && (( qual[i]-=10000 )) + sortline="${sortline}${qual[i]} ${i}\n" + done + + sortline=( $( echo -e "${sortline}" | sort -nr ) ) + + for (( i=0; i<${#mac[@]}; i++ )); do + (( x=(i * 2) + 1 )) + mac_APs[i]="${mac[${sortline[x]}]}" + essid_APs[i]="${essid[${sortline[x]}]}" + mode_APs[i]="${mode[${sortline[x]}]}" + enc_APs[i]="${enc[${sortline[x]}]}" + done + + return 0 +} + +# void iwconfig_scan_report(void) +# +# Report the results of the scan and re-map any ESSIDs if they +# have been configured for the MAC address found +iwconfig_scan_report() { + local i k m remove + local -a u + + [[ -z ${mac_APs} ]] && ewarn " no access points found" + + # We need to do the for loop like this so we can + # dynamically remove from the array + eindent + for ((i=0; i<${#mac_APs[@]}; i++)); do + k="" + [[ ${enc_APs[i]} == "yes" ]] && k="(WEP required)" + + if [[ -z ${essid_APs[i]} ]]; then + veinfo "Found ${mac_APs[i]} ${k}" + else + veinfo "Found \"${essid_APs[i]//\\\\/\\\\}\" at ${mac_APs[i]} ${k}" + fi + + eindent + + eval m=\"\$\{mac_essid_${mac_APs[i]//:/}\}\" + if [[ -n ${m} ]]; then + essid_APs[i]="${m}" + veinfo "mapping to \"${m//\\\\/\\\\}\"" + fi + + remove=false + # If we don't know the essid then we cannot connect to them + # so we remove them from our array + if [[ -z ${essid_APs[i]} ]]; then + remove=true + else + for k in "${blacklist_aps[@]}"; do + if [[ ${k} == "${essid_APs[i]}" ]]; then + vewarn "\"${k//\\\\/\\\\}\" has been blacklisted - not connecting" + remove=true + break + fi + done + fi + + eoutdent + + ${remove} && u=( "${u[@]}" "${i}" ) + done + + eoutdent + + # Now we remove any duplicates + for ((i=0; i < ${#essid_APs[@]} - 1; i++)); do + for ((j=${i} + 1; j <${#essid_APs[@]}; j++)); do + [[ ${essid_APs[i]} == "${essid_APs[j]}" ]] && u=( "${u[@]}" "${j}" ) + done + done + + for i in ${u[@]}; do + unset essid_APs[i] + unset mode_APs[i] + unset mac_APs[i] + unset enc_APs[i] + done + + # We need to squash our arrays so indexes work again + essid_APs=( "${essid_APs[@]}" ) + mode_APs=( "${mode_APs[@]}" ) + mac_APs=( "${mac_APs[@]}" ) + enc_APs=( "${enc_APs[@]}" ) +} + +# bool iwconfig_force_preferred(char *iface) +# +# Forces the preferred_aps list to associate in order +# but only if they were not picked up by our scan +iwconfig_force_preferred() { + local iface=$1 essid i + + [[ -z ${preferred_aps} ]] && return 1 + + ewarn "Trying to force preferred in case they are hidden" + for essid in "${preferred_aps[@]}"; do + local found_AP=false + for ((i = 0; i < ${#mac_APs[@]}; i++)); do + if [[ ${essid} == "${essid_APs[i]}" ]]; then + found_AP=true + break + fi + done + if ! ${found_AP} ; then + ESSID="${essid}" + iwconfig_associate "${iface}" && return 0 + fi + done + + ewarn "Failed to associate with any preferred access points on ${iface}" + return 1 +} + +# bool iwconfig_connect_preferred(char *iface) +# +# Connects to preferred_aps in order if they were picked up +# by our scan +iwconfig_connect_preferred() { + local iface="$1" essid i + + for essid in "${preferred_aps[@]}"; do + for ((i=0; i<${#essid_APs[@]}; i++)); do + if [[ ${essid} == "${essid_APs[i]}" ]]; then + ESSID="${essid}" + iwconfig_associate "${iface}" "${mode_APs[i]}" "${mac_APs[i]}" \ + "${enc_APs[i]}" && return 0 + break + fi + done + done + + return 1 +} + +# bool iwconfig_connect_not_preferred(char *iface) +# +# Connects to any AP's found that are not in +# our preferred list +iwconfig_connect_not_preferred() { + local iface=$1 i ap has_preferred + + for ((i=0; i<${#mac_APs[@]}; i++)); do + has_preferred=false + for ap in "${preferred_aps[@]}"; do + if [[ ${ap} == "${essid_APs[i]}" ]]; then + has_preferred=true + break + fi + done + if ! ${has_preferred} ; then + ESSID="${essid_APs[i]}" + iwconfig_associate "${iface}" "${mode_APs[i]}" "${mac_APs[i]}" \ + "${enc_APs[i]}" && return 0 + fi + done + + return 1 +} + +# void iwconfig_defaults(char *iface) +# +# Apply some sane defaults to the wireless interface +# incase the user already applied some changes +iwconfig_defaults() { + local iface="$1" + + # Set some defaults + iwconfig "${iface}" rate auto &>/dev/null + iwconfig "${iface}" rts off &>/dev/null + iwconfig "${iface}" frag off &>/dev/null + iwconfig "${iface}" power off &>/dev/null + iwconfig "${iface}" txpower auto &>/dev/null + iwconfig "${iface}" key [1] off &>/dev/null + iwconfig "${iface}" mode managed &>/dev/null +} + +# void iwconfig_strip_associated(char *iface) +# +# We check to see which ifaces have associated AP's except for the iface +# given and remove those AP's from the scan list +# We also remove from the preferred list +iwconfig_strip_associated() { + local iface="$1" e a j + local essid=$( iwconfig_get_essid "${iface}" ) + local -a ifaces=( $( iwconfig 2>/dev/null | grep -o "^\w*" ) ) + + for i in "${ifaces[@]}"; do + [[ ${i} == ${iface} ]] && continue + interface_is_up "${i}" || continue + iwconfig_test_associated "${i}" || continue + e=$( iwconfig_get_essid "${i}" ) + u=() + for ((j=0; j<${#mac_APs[@]}; j++)); do + if [[ ${essid_APs[j]} == "${e}" ]]; then + ewarn "${e} has already been associated with ${i}" + unset essid_APs[j] + unset mode_Aps[j] + unset mac_APs[j] + unset enc_APs[j] + # We need to squash our arrays so that indexes work + essid_APs=( "${essid_APs[@]}" ) + mode_APs=( "${mode_APs[@]}" ) + mac_APs=( "${mac_APs[@]}" ) + enc_APs=( "${enc_APs[@]}" ) + break + fi + done + for ((j=0; j<${#preferred_aps[@]}; j++)); do + if [[ ${preferred_aps[j]} == "${e}" ]]; then + unset preferred_aps[j] + preferred_aps=( "${preferred_aps[@]}" ) + break + fi + done + done +} + +# bool iwconfig_configure(char *iface) +# +# The main startup code +# First we bring the interface up, apply defaults, apply user configuration +# Then we test to see if ad-hoc mode has been requested and branch if needed +# Then we scan for access points and try to connect to them in a predetermined order +# Once we're connected we show a report and then configure any interface +# variables for the ESSID +iwconfig_configure() { + local iface="$1" test x e ifvar=$( bash_variable "$1" ) + local -a essid_APs mac_APs mode_APs enc_APs + + iwconfig_defaults "${iface}" + iwconfig_user_config "${iface}" + + eval ESSID=\"\$\{essid_${ifvar}\}\" + + # Setup ad-hoc mode? + x=$( eval echo \"\$\{mode_${ifvar}:-managed\}\" | tr '[:upper:]' '[:lower:]' ) + if [[ ${x} == "ad-hoc" || ${x} == "master" ]]; then + iwconfig_setup_specific "${iface}" "${x}" + return $? + fi + + if [[ ${x} != "managed" && ${x} != "auto" ]]; then + eerror "Only managed, ad-hoc, master and auto modes are supported" + return 1 + fi + + # We only change the mode if it's not the same as some drivers + # only do managed and throw an error changing to managed + local cur_mode=$( iwconfig_get_mode "${iface}" ) + if [[ ${cur_mode} != "${x}" ]]; then + if ! iwconfig "${iface}" mode "${x}" ; then + eerror "${iface} does not support setting the mode to \"${x}\"" + return 1 + fi + fi + + # These arrays hold the results of our scan + local -a mac_APs essid_APs enc_APs + + # Has an ESSID been forced? + if [[ -n ${ESSID} ]]; then + iwconfig_associate "${iface}" && return 0 + [[ ${ESSID} == "any" ]] && iwconfig_force_preferred "${iface}" && return 0 + + eval ESSID=\"\$\{adhoc_essid_${ifvar}\}\" + if [[ -n ${ESSID} ]]; then + iwconfig_setup_specific "${iface}" ad-hoc + return $? + fi + return 1 + fi + + # Do we have a preferred Access Point list specific to the interface? + eval x=( \"\$\{preferred_aps_${ifvar}\[@\]\}\" ) + [[ -n ${x} ]] && preferred_aps=( "${x[@]}" ) + + # Do we have a blacklist Access Point list specific to the interface? + eval x=( \"\$\{blacklist_aps_${ifvar}\[@\]\}\" ) + [[ -n ${e} ]] && blacklist_aps=( "${x[@]}" ) + + # Are we forcing preferred only? + eval x=\"\$\{associate_order_${ifvar}\}\" + [[ -n ${x} ]] && associate_order="${x}" + associate_order=$( echo "${associate_order:-any}" | tr '[:upper:]' '[:lower:]' ) + + if [[ ${associate_order} == "forcepreferredonly" ]]; then + iwconfig_force_preferred "${iface}" && return 0 + else + iwconfig_scan "${iface}" || return 1 + iwconfig_scan_report + + # Strip AP's from the list that have already been associated with + # other wireless cards in the system if requested + eval x=\"\$\{unique_ap_${ifvar}\}\" + [[ -n ${x} ]] && unique_ap="${x}" + unique_ap=$( echo "${unique_ap:-no}" | tr '[:upper:]' '[:lower:]' ) + [[ ${unique_ap} != "no" ]] && iwconfig_strip_associated "${iface}" + + iwconfig_connect_preferred "${iface}" && return 0 + [[ ${associate_order} == "forcepreferred" \ + || ${associate_order} == "forceany" ]] \ + && iwconfig_force_preferred "${iface}" && return 0 + [[ ${associate_order} == "any" || ${associate_order} == "forceany" ]] \ + && iwconfig_connect_not_preferred "${iface}" && return 0 + fi + + e="associate with" + [[ -z ${mac_APs} ]] && e="find" + [[ ${preferred_only} == "force" || ${preferred_aps} == "forceonly" ]] \ + && e="force" + e="Couldn't ${e} any access points on ${iface}" + + eval ESSID=\"\$\{adhoc_essid_${ifvar}\}\" + if [[ -n ${ESSID} ]]; then + ewarn "${e}" + iwconfig_setup_specific "${iface}" ad-hoc + return $? + fi + + if ${IN_BACKGROUND}; then + export IN_BACKGROUND + /etc/init.d/net.${iface} stop & + exit 0 + fi + + eerror "${e}" + return 1 +} + +# bool iwconfig_pre_start(char *iface) +# +# Start entry point +# First we check if wireless extensions exist on the interface +# If they are then we configue wireless +iwconfig_pre_start() { + local iface="$1" r=0 + + # We don't configure wireless if we're being called from + # the background + ${IN_BACKGROUND} && return 0 + + save_options "ESSID" "" + interface_exists "${iface}" || return 0 + + # We need to bring the interface up, as some cards do not register + # in /proc/wireless until they are brought up. + interface_up "${iface}" + + if ! iwconfig_check_extensions "${iface}" ; then + veinfo "Wireless extensions not found for ${iface}" + return 0 + fi + + # Check for rf_kill - only ipw supports this at present, but other + # cards may in the future. + if [[ -e "/sys/class/net/${iface}/device/rf_kill" ]]; then + if [[ $( < "/sys/class/net/${iface}/device/rf_kill" ) != 0 ]]; then + eerror "Wireless radio has been killed for interface ${iface}" + return 1 + fi + fi + + einfo "Configuring wireless network for ${iface}" + + # Are we a proper IEEE device? + # Most devices reutrn IEEE 802.11b/g - but intel cards return IEEE in lower case + # and RA cards return RAPCI or similar which really sucks :( + # For the time being, we will test prism54 not loading firmware which reports + # NOT READY! + x=$( iwconfig_get_type "${iface}" ) + if [[ ${x} == "NOT READY!" ]]; then + eerror "Looks like there was a probem loading the firmware for ${iface}" + return 1 + fi + + # Setup IFS incase parent script has modified it + local IFS=$' '$'\n'$'\t' + + if [[ ${background} == "yes" ]]; then + IN_BACKGROUND=true + iwconfig_configure "${iface}" &>/dev/null \ + && save_options "ESSID" "${ESSID}" \ + || iwconfig_defaults "${iface}" \ + && interface_down "${iface}" \ + && mark_service_stopped "net.${iface}" \ + & + go_background + fi + + if iwconfig_configure "${iface}" ; then + save_options "ESSID" "${ESSID}" + return 0 + fi + + eerror "Failed to configure wireless for ${iface}" + iwconfig_defaults "${iface}" + unset ESSID ESSIDVAR + interface_down "${iface}" + return 1 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/macchanger b/net-scripts/net.modules.d/macchanger new file mode 100644 index 0000000..7cc2c5b --- /dev/null +++ b/net-scripts/net.modules.d/macchanger @@ -0,0 +1,126 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* macchanger_provides(void) +# +# Returns a string to change module definition for starting up +macchanger_provides() { + echo "macchanger" +} + +# void macchanger_depend(void) +# +# Sets up the dependancies for the module +macchanger_depend() { + before macnet +} + +# bool macchanger_check_installed(void) +# +# macchanger is always installed as an interface can change to a specific +# mac address, and an interface is always installed +macchanger_check_installed() { + return 0 +} + +# bool macchanger_check_depends(void) +# +# Checks to see if we have the needed functions +macchanger_check_depends() { + local f + + for f in interface_get_mac_address interface_set_mac_address; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "macchanger: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool macchanger_pre_start(char *iface) +# +# Configures the MAC address for iface +macchanger_pre_start() { + # We don't change MAC addresses from background + ${IN_BACKGROUND} && return 0 + + local iface="$1" mac opts ifvar=$( bash_variable "$1" ) + + eval mac=\"\$\{mac_${ifvar}\}\" + [[ -z ${mac} ]] && return 0 + + interface_exists "${iface}" true || return 1 + + ebegin "Changing MAC address of ${iface}" + + mac=$( echo "${mac}" | tr '[:upper:]' '[:lower:]' ) + case "${mac}" in + # specific mac-addr, i wish there were a shorter way to specify this + [0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]) + # We don't need macchanger to change to a specific mac address + interface_set_mac_address "${iface}" "${mac}" + eend "$?" + if [[ $? == "0" ]]; then + mac=$( interface_get_mac_address "${iface}" ) + eindent + einfo "changed to ${mac}" + eoutdent + return 0 + fi + ;; + + # increment MAC address, default macchanger behavior + increment) opts="${opts}" ;; + + # randomize just the ending bytes + random-ending) opts="${opts} -e" ;; + + # keep the same kind of physical layer (eg fibre, copper) + random-samekind) opts="${opts} -a" ;; + + # randomize to any known vendor of any physical layer type + random-anykind) opts="${opts} -A" ;; + + # fully random bytes + random-full) opts="${opts} -r" ;; + + # default case is just to pass on all the options + *) opts="${opts} ${mac}" ;; + esac + + if [[ ! -x /sbin/macchanger ]]; then + eerror "For changing MAC addresses, emerge net-analyzer/macchanger" + return 1 + fi + + # The interface needs to be up for macchanger to work most of the time + interface_down "${iface}" + + mac=$( /sbin/macchanger ${opts} "${iface}" \ + | sed -n -e 's/^Faked MAC:.*\<\(..:..:..:..:..:..\)\>.*/\U\1/p' ) + + # Sometimes the interface needs to be up .... + if [[ -z ${mac} ]]; then + interface_up "${iface}" + mac=$( /sbin/macchanger ${opts} "${iface}" \ + | sed -n -e 's/^Faked MAC:.*\<\(..:..:..:..:..:..\)\>.*/\U\1/p' ) + fi + + if [[ -z ${mac} ]]; then + eend 1 "Failed to set MAC address" + return 1 + fi + + eend 0 + eindent + einfo "changed to ${mac}" + eoutdent + + return 0 #important +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/macnet b/net-scripts/net.modules.d/macnet new file mode 100644 index 0000000..3ab8cd1 --- /dev/null +++ b/net-scripts/net.modules.d/macnet @@ -0,0 +1,72 @@ +#!/bin/bash +# Copyright (c) 2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) +# Many thanks to all the people in the Gentoo forums for their ideas and +# motivation for me to make this and keep on improving it + +# void macnet_depend(void) +# +# Sets up the dependancies for the module +macnet_depend() { + before interface wireless + after macchanger +} + +# bool macnet_check_installed(void) +# +# Always returns 0 as we are "installed" by wireless in the depend function +macnet_check_installed() { + return 0 +} + +# char* macnet_provides(void) +# +# Returns a string to change module definition for starting up +macnet_provides() { + echo "macnet" +} + +# bool macnet_check_depends(void) +# +# Checks to see if we have the needed functions +macnet_check_depends() { + local f + + for f in interface_get_mac_address; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "macnet: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool macnet_start(char *iface) +# +# All interfaces and module scripts expose modulename_get_vars +# which returns a space seperated list of user configuration variables +# We can override each variable here from a given MAC address of the interface +# Always returns 0 +macnet_pre_start() { + local iface="$1" + + interface_exists "${iface}" || return 0 + + # We need to bring the interface up for some interfaces, otherwise the MAC + # address isn't consistent - mainly wireless cards with firmware uploading. + interface_up "${iface}" + + local mac=$( interface_get_mac_address "${iface}" ) + [[ -z ${mac} ]] && return 0 + + vebegin "Configuring ${iface} for MAC address ${mac}" 2>/dev/null + mac="${mac//:}" + configure_variables "${iface}" "${mac}" + veend 0 2>/dev/null + + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/netplugd b/net-scripts/net.modules.d/netplugd new file mode 100644 index 0000000..4dc872f --- /dev/null +++ b/net-scripts/net.modules.d/netplugd @@ -0,0 +1,143 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* netplugd_provides(void) +# +# Returns a string to change module definition for starting up +netplugd_provides() { + echo "plug" +} + +# void netplugd_depend(void) +# +# Sets up the dependancies for the module +netplugd_depend() { + after macnet + before interface +} + +# bool netplugd_check_installed(void) +# +# Returns 0 if netplug is installed, otherwise 1 +netplugd_check_installed() { + if [[ ! -x /sbin/netplugd ]]; then + ${1:-false} && eerror "For netplug support, emerge sys-apps/netplug" + return 1 + fi + return 0 +} + +# bool netplugd_check_depends(void) +# +# Checks to see if we have the needed functions +netplugd_check_depends() { + local f + + for f in interface_exists interface_get_mac_address ; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "netplugd: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool netplugd_pre_start(char *interface) +# +# Start netplug on an interface +netplugd_pre_start() { + local iface="$1" timeout i + local pidfile="/var/run/netplugd.${iface}.pid" + + # We don't start netplug if we're being called from the background + ${IN_BACKGROUND} && return 0 + + interface_exists "${iface}" || return 0 + + # We need a valid MAC address + # It's a basic test to ensure it's not a virtual interface + local mac=$(interface_get_mac_address "${iface}") + if [[ -z ${mac} ]]; then + vewarn "netplug only works on interfaces with a valid MAC address" + return 0 + fi + + # We don't work on bridges + if [[ $(type -t bridge_exists) == "function" ]]; then + if bridge_exists "${iface}"; then + veinfo "netplug does not work on bridges" + return 0 + fi + fi + + # We don't work on wirelesss interfaces + if [[ $(type -t wireless_check_extensions) == "function" ]]; then + if wireless_check_extensions "${iface}"; then + veinfo "netplug does not work on wireless interfaces" + return 0 + fi + fi + + ebegin "Starting netplug on ${iface}" + + # We need the interface up for netplug to listen to netlink events + interface_up "${iface}" + + # Mark the us as inactive so netplug can restart us + mark_service_inactive "net.${iface}" + + # Start netplug + start-stop-daemon --start --exec /sbin/netplugd \ + --pidfile "${pidfile}" \ + -- -i "${iface}" -P -p "${pidfile}" -c /dev/null + eend "$?" || return 1 + + eindent + + eval timeout=\"\$\{plug_timeout_${ifvar}\:-10}\" + if [[ ${timeout} == "0" ]]; then + ewarn "WARNING: infinite timeout set for ${iface} to come up" + elif [[ ${timeout} -lt 0 ]]; then + ewarn "WARNING: negative timeout set for ${iface}" + exit 0 + fi + + veinfo "Waiting for ${iface} to be marked as started" + + i=0 + while true ; do + if service_started "net.${iface}"; then + local addr=$( interface_get_address "${iface}" ) + einfo "${iface} configured with address ${addr}" + exit 0 + fi + sleep 1 + (( i++ )) + [[ ${i} == "${timeout}" || ${i} -gt "${timeout}" ]] && break + done + + eend 1 "Failed to configure ${iface} in the background" + exit 0 +} + +# bool netplugd_post_stop(char *iface) +# +# Stops netplug on an interface +# Returns 0 (true) when successful, non-zero otherwise +netplugd_post_stop() { + ${IN_BACKGROUND} && return 0 + local iface="$1" + local pidfile="/var/run/netplugd.${iface}.pid" + + [[ ! -e ${pidfile} ]] && return 0 + + ebegin "Stopping netplug on ${iface}" + start-stop-daemon --stop --exec /sbin/netplugd \ + --pidfile "${pidfile}" + eend $? +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/pppd b/net-scripts/net.modules.d/pppd new file mode 100644 index 0000000..a9017a4 --- /dev/null +++ b/net-scripts/net.modules.d/pppd @@ -0,0 +1,268 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# char* pppd_provides(void) +# +# Returns a string to change module definition for starting up +pppd_provides() { + echo "ppp" +} + +# void pppd_depend(void) +# +# Sets up the dependancies for the module +pppd_depend() { + after interface + before dhcp +} + +# bool pppd_check_installed(void) +# +# Returns 1 if pppd is installed, otherwise 0 +pppd_check_installed() { + if [[ ! -x /usr/sbin/pppd ]]; then + ${1:-false} && eerror "For PPP support, emerge net-dialup/ppp" + return 1 + fi + return 0 +} + +# bool pppd_check_depends(void) +# +# Checks to see if we have the needed functions +pppd_check_depends() { + return 0 +} + +# char *pppd_regex_escape(char *string) +# +# Returns the supplied string with any special regex +# characters escaped so they don't provide regex intructions +# This may be a candidate for adding to /sbin/functions.sh or +# net-scripts functions at some point +pppd_regex_escape() { + local escaped_result="$*" + escaped_result=${escaped_result//\\/\\\\} + escaped_result=${escaped_result//./\\.} + escaped_result=${escaped_result//+/\\+} + escaped_result=${escaped_result//(/\\(} + escaped_result=${escaped_result//)/\\)} + escaped_result=${escaped_result//[/\\[} + escaped_result=${escaped_result//]/\\]} + escaped_result=${escaped_result//\{/\\\{} + escaped_result=${escaped_result//\}/\\\}} + escaped_result=${escaped_result//\?/\\\?} + escaped_result=${escaped_result//\*/\\\*} + escaped_result=${escaped_result//\//\\/} + escaped_result=${escaped_result//|/\\|} + escaped_result=${escaped_result//&/\\&} + escaped_result=${escaped_result//~/\\~} + escaped_result=${escaped_result//^/\\^} + escaped_result=${escaped_result//$/\\$} + echo $escaped_result +} + +# bool pppd_update_secrets_file(char* filepath, char* username, \ +# char* remotename, char* password) +# +# Add/update PAP/CHAP authentication information +pppd_update_secrets_file() { + local filepath="$1" username="$2" remotename="$3" password="$4" + if [[ ! -f ${filepath} ]]; then + touch ${filepath} && \ + chmod 0600 ${filepath} || \ + return 1 + fi + + #escape username and remotename, used in following sed calls + local regex_username=$(pppd_regex_escape ${username}) + local regex_remotename=$(pppd_regex_escape ${remotename}) + local regex_password + local regex_filter="[ \t]*\"?${regex_username}\"?[ \t]*\"?${regex_remotename}\"?[ \t]*" + + #read old password, including " chars + #for being able to distinct when we need to add or update auth info + local old_password=$( + sed -r -e "/^${regex_filter}\".*\"[ \t]*\$/\ + {s/^${regex_filter}(\".*\")[ \t]*\$/\1/;q;};\ + d;" \ + ${filepath} + ) + + if [[ -z "${old_password}" ]]; then + regex_username=${username//\\/\\\\} + regex_remotename=${remotename//\\/\\\\} + regex_password=${password//\\/\\\\} + regex_password=${password//"/\\"} + sed -r -i -e "\$a\"${regex_username}\" ${regex_remotename} \"${regex_password}\"" ${filepath} + vewarn "Authentication info has been added to ${filepath}" + elif [[ "\"${password//\"/\\\"}\"" != "${old_password}" ]]; then + regex_password=${password//\\/\\\\} + regex_password=${regex_password//\//\\/} + regex_password=${regex_password//&/\\&} + regex_password=${regex_password//\"/\\\\\"} + sed -r -i -e "s/^(${regex_filter}\").*(\"[ \t]*)\$/\1${regex_password}\2/" ${filepath} + vewarn "Authentication info has been updated in ${filepath}" + fi + return 0 +} + +# bool pppd_start(char *iface) +# +# Start PPP on an interface by calling pppd +# +# Returns 0 (true) when successful, otherwise 1 +pppd_start() { + local iface="$1" ifvar=$( bash_variable "$1" ) opts="" link + if [[ ${iface%%[0-9]*} != "ppp" ]]; then + eerror "PPP can only be invoked from net.ppp[0-9]" + return 1 + fi + + local unit="${iface#ppp}" + if [[ -z ${unit} ]] ; then + eerror "PPP requires a unit - use net.ppp[0-9] instead of net.ppp" + return 1 + fi + + # PPP requires a link to communicate over - normally a serial port + # PPPoE communicates over ethernet + # PPPoA communictes over ATM + # In all cases, the link needs to be available before we start PPP + eval link=\"\$\{link_${ifvar}\}\" + if [[ -z ${link} ]]; then + eerror "link_${ifvar} has not been set in /etc/conf.d/net" + return 1 + fi + + # Might or might not be set in conf.d/net + local user password i + eval username=\"\$\{username_${ifvar}\}\" + eval password=\"\$\{password_${ifvar}\}\" + + #Add/update info in PAP/CHAP secrets files + if [[ -n ${username} && -n ${password} ]]; then + for i in chap pap ; do + if ! pppd_update_secrets_file "/etc/ppp/${i}-secrets" \ + "${username}" "${iface}" "${password}" ; then + eerror "Failed to update /etc/ppp/${i}-secrets" + return 1 + fi + done + fi + + # Load any commandline options + eval opts=\"\$\{pppd_${ifvar}\[@\]}\" + + # We don't work if nodetach or unit is set + for i in nodetach updetach unit ; do + if [[ " ${opts} " == *" ${i} "* ]]; then + eerror "The option \"${i}\" is not allowed" + return 1 + fi + done + + # Check for mtu/mru + local mtu + eval mtu=\"\$\{mtu_${ifvar}\}\" + if [[ -n ${mtu} ]]; then + [[ " ${opts} " != *" mtu "* ]] && opts="${opts} mtu ${mtu}" + [[ " ${opts} " != *" mru "* ]] && opts="${opts} mru ${mtu}" + fi + + # Detach if we're not idling + [[ " ${opts} " != *" idle "* && " ${opts} " != *" updetach "* ]] \ + && opts="${opts} updetach" + + # Setup auth info + [[ -n ${username} ]] && opts="user \"${username}\" ${opts}" + opts="remotename ${iface} ${opts}" + + # Load a custom interface configuration file if it exists + [[ -f "/etc/ppp/options.${iface}" ]] \ + && opts="${opts} file /etc/ppp/options.${iface}" + + # Set forced options + opts="unit ${unit} persist maxfail 0 ${opts}" + + # Setup connect script + local -a chat + eval chat=( \"\$\{chat_${ifvar}\[@\]\}\" ) + if [[ -n "${chat[@]}" ]]; then + opts="${opts} connect \"/usr/sbin/chat -e -E -v" + + local -a phone_number + eval phone_number=( \"\$\{phone_number_${ifvar}\}\" ) + if [[ ${#phone_number[@]} -ge 1 ]]; then + opts="${opts} -T '${phone_number[0]}'" + if [[ ${#phone_number[@]} -ge 2 ]]; then + opts="${opts} -U '${phone_number[1]}'" + fi + fi + + for (( i=0; i<${#chat[@]}; i++ )); do + opts="${opts} '${chat[i]}'" + done + + opts="${opts}\"" + fi + + # Add plugins + local -a plugins + eval plugins=( \"\$\{plugins_${ifvar}\[@\]\}\" ) + if [[ -n "${plugins[@]}" ]]; then + for (( i=0; i<${#plugins[@]}; i++ )); do + local -a plugin=( ${plugins[i]} ) + # Bound to be some users who do this + [[ ${plugin[0]} == "pppoe" ]] && plugin[0]="rp-pppoe" + [[ ${plugin[0]} == "pppoa" ]] && plugin[0]="pppoatm" + [[ ${plugin[0]} == "capi" ]] && plugin[0]="capiplugin" + + [[ ${plugin[0]} == "rp-pppoe" ]] && opts="${opts} connect true" + opts="${opts} plugin ${plugin[0]}.so ${plugin[@]:1}" + [[ ${plugin[0]} == "rp-pppoe" ]] && opts="${opts} ${link}" + done + fi + + #Specialized stuff. Insert here actions particular to connection type (pppoe,pppoa,capi) + local insert_link_in_opts=1 + if [[ " ${opts} " == *" plugin rp-pppoe.so "* ]]; then + # Ensure that the link exists and is up + interface_exists "${link}" true || return 1 + interface_up "${link}" + + # Load the pppoe kernel module - if this fails, we have to hope + # that pppoe support is compiled into the kernel + modprobe pppoe 2>/dev/null + + insert_link_in_opts=0 + fi + [[ ${insert_link_in_opts} -eq 0 ]] || opts="${link} ${opts}" + + ebegin "Running pppd" + i=$( eval /usr/sbin/pppd ${opts} ) + eend $? "${i}" || return 1 + + local addr=$( interface_get_address "${iface}" ) + einfo "${iface} received address ${addr}" +} + +# bool pppd_stop(char *iface) +# +# Stop PPP link by killing the associated pppd process +# +# Returns 0 (true) if no process to kill or it terminates successfully, +# otherwise non-zero (false) +pppd_stop() { + local iface="$1" pidfile="/var/run/$1.pid" + + [[ ! -s ${pidfile} ]] && return 0 + + local pid=$(<"${pidfile}") + einfo "Stopping pppd on ${iface}" + kill -s TERM "${pid}" + process_finished "${pid}" /usr/sbin/pppd + + eend $? +} diff --git a/net-scripts/net.modules.d/pump b/net-scripts/net.modules.d/pump new file mode 100644 index 0000000..95eb61a --- /dev/null +++ b/net-scripts/net.modules.d/pump @@ -0,0 +1,136 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +pump() { + LC_ALL=C /sbin/pump "$@" +} + +# char* pump_provides(void) +# +# Returns a string to change module definition for starting up +pump_provides() { + echo "dhcp" +} + +# void pump_depend(void) +# +# Sets up the dependancies for the module +pump_depend() { + after interface +} + +# bool pump_check_installed(void) +# +# Returns 1 if pump is installed, otherwise 0 +pump_check_installed() { + [[ -x /sbin/pump ]] && return 0 + ${1:-false} && eerror "For DHCP (pump) support, emerge net-misc/pump" + return 1 +} + +# bool pump_check_depends(void) +# +# Checks to see if we have the needed functions +pump_check_depends() { + local f + + for f in interface_exists interface_get_address; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "pump: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# char* pump_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +pump_get_vars() { + echo "pump_$1 dhcp_$1" +} + +# bool pump_stop(char *iface) +# +# Stop pump on an interface +# Return 0 if pump is not running or we stop it successfully +# Otherwise 1 +pump_stop() { + local iface="$1" count e + + pump_check_installed || return 0 + + # We check for a pump process first as querying for status + # causes pump to spawn a process + pidof /sbin/pump &>/dev/null || return 0 + + # Check that pump is running on the interface + pump --status --interface "${iface}" 2>/dev/null \ + | grep -q "^Device ${iface}" || return 0 + + # Pump always releases the lease + ebegin "Stopping pump on ${iface}" + pump --release --interface "${iface}" + eend "$?" "Failed to stop pump" + return "$?" +} + +# bool pump_start(char *iface) +# +# Start pump on an interface by calling pumpcd $iface $options +# +# Returns 0 (true) when a dhcp address is obtained, otherwise +# the return value from pump +pump_start() { + local iface="$1" opts d ifvar=$( bash_variable "$1" ) search + + interface_exists "${iface}" true || return 1 + + eval opts=\" \$\{pump_${ifvar}\} \" + + # Map some generic options to pump + eval d=\" \$\{dhcp_${ifvar}\} \" + [[ ${d} == " " ]] && d=" ${dhcp} " + [[ ${d} == *" nodns "* ]] && opts="${opts} --no-dns" + [[ ${d} == *" nogateway "* ]] && opts="${opts} --no-gateway" + [[ ${d} == *" nontp "* ]] && opts="${opts} --no-ntp" + + eval search=\"\$\{dns_search_${ifvar}\}\" + [[ -n ${search} ]] && opts="${opts} --search-path='"${search}"'" + + # Add our route metric + eval metric=\"\$\{metric_${ifvar}\}\" + [[ -n ${metric} ]] && opts="${opts} --route-metric ${metric}" + + [[ ! -d "${statedir}/${iface}" ]] && mkdir -m 0755 -p "${statedir}/${iface}" + + opts="${opts} --win-client-ident --etc-dir=${statedir}/${iface}" + opts="${opts} --script /lib/rcscripts/net.modules.d/helpers.d/pump-wrapper" + opts="${opts} --keep-up --interface ${iface}" + + # Bring up DHCP for this interface (or alias) + ebegin "Running pump" + + if [[ ${background} == "yes" ]]; then + eval pump ${opts} & + eend 0 + go_background + fi + + eval pump ${opts} + eend "$?" || return "$?" + + # pump succeeded, show address retrieved + local addr=$( interface_get_address "${iface}" ) + einfo "${iface} received address ${addr}" + + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/rename b/net-scripts/net.modules.d/rename new file mode 100644 index 0000000..ddab8b0 --- /dev/null +++ b/net-scripts/net.modules.d/rename @@ -0,0 +1,86 @@ +#!/bin/bash +# Copyright (c) 2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# char* rename_provides(void) +# +# Returns a string to change module definition for starting up +rename_provides() { + echo "rename" +} + +# void rename_depend(void) +# +# Sets up the dependancies for the module +rename_depend() { + after macchanger macnet + before wireless interface +} + +# bool rename_check_installed(void) +# +# We are always installed +rename_check_installed() { + return 0 +} + +# bool rename_check_depends(void) +# +# Checks to see if we have the needed functions +rename_check_depends() { + return 0 +} + +# char* rename_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +rename_get_vars() { + echo "rename_$1" +} + +# bool rename_pre_start(char *iface) +# +# Checks to see if we have to rename the interface +rename_pre_start() { + local iface="$1" newname="" mac ifvar=$( bash_variable "$1" ) + + interface_exists "${iface}" || return 0 + + eval newname=\"\$\{rename_${ifvar}\}\" + [[ -z ${newname} || ${iface} == "${newname}" ]] && return 0 + + # We cannot rename vlan interfaces as /proc/net/vlan/config always + # returns the old interface name. We don't bail out though as it's + # not critical that the interface gets renamed. + if [[ -d /proc/net/vlan/config ]] ; then + if grep -q "^eth0.2 " /proc/net/vlan/config ; then + eerror "Cannot rename VLAN interfaces" + return 0 + fi + fi + + ebegin "Renaming \"${iface}\" to \"${newname}\"" + + # Ensure that we have an init script + [[ ! -e "/etc/init.d/net.${newname}" ]] \ + && ( cd /etc/init.d ; ln -s net.lo "net.${newname}" ) + + # Ensure that the interface is down and without any addresses or we + # will not work + interface_del_addresses "${iface}" + interface_down "${iface}" + interface_set_name "${iface}" "${newname}" + eend "$?" "Failed to rename interface" || return 1 + + # Mark us as stopped, start the new interface and bail cleanly + mark_service_stopped "net.${iface}" + einfo "Stopped configuration of ${iface} due to renaming" + service_stopped "net.${newname}" && start_service "net.${newname}" + + exit 1 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/system b/net-scripts/net.modules.d/system new file mode 100644 index 0000000..c8bd0ff --- /dev/null +++ b/net-scripts/net.modules.d/system @@ -0,0 +1,162 @@ +#!/bin/bash +# Copyright (c) 2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# void system_depend(void) +# +# Sets up the dependancies for the module +system_depend() { + after interface essidnet + before dhcp +} + +# bool system_check_installed(void) +# +# Always returns 0 as we are writing to files +system_check_installed() { + return 0 +} + +# char* system_provides(void) +# +# Returns a string to change module definition for starting up +system_provides() { + echo "system" +} + +# bool system_check_depends(void) +# +# Checks to see if we have the needed functions +system_check_depends() { + return 0 +} + +# char* ifconfig_get_vars(char *interface) +# +# Returns a string spaced with possible user set configuration variables +system_get_vars() { + echo "dns_servers_$1 dns_domain_$1 dns_options_$1 dns_search_$1 dns_sortlist_$1 ntp_servers_$1 nis_domain_$1 nis_servers_$1" +} + +system_dns_extra() { + local iface="$1" ifvar=$( bash_variable "$1" ) out="$2" x sortlist + local -a options + + eval options=( \"\$\{dns_options_${ifvar}\[@\]\}\" ) + [[ -z ${options} ]] && options=( "${dns_options[@]}" ) + for x in "${options[@]}"; do + echo "options ${x}" >> "${out}" + done + + eval sortlist=\"\$\{dns_sortlist_${ifvar}\}\" + [[ -z ${sortlist} ]] && sortlist="${dns_sortlist}" + [[ -n ${sortlist} ]] && echo "sortlist ${sortlist}" >> "${out}" +} + +system_dns() { + local iface="$1" ifvar=$( bash_variable "$1" ) x domain search + local conffile="${statedir}/${iface}/resolv.conf" tmpfile="${conffile}.$$" + local -a servers + + eval servers=( \"\$\{dns_servers_${ifvar}\[@\]\}\" ) + [[ -z ${servers} ]] && servers=( "${dns_servers[@]}" ) + + eval domain=\"\$\{dns_domain_${ifvar}\}\" + [[ -z ${domain} ]] && domain="${dns_domain}" + + eval search=\"\$\{dns_search_${ifvar}\}\" + [[ -z ${search} ]] && search="${dns_search}" + + [[ -z ${servers} && -z ${domain} && -z ${search} ]] && return 0 + + echo "# Generated by net-scripts for interface ${iface}" > "${tmpfile}" + chmod 644 "${tmpfile}" + + [[ -n ${domain} ]] && echo "domain ${domain}" >> "${tmpfile}" + + for x in ${servers[@]}; do + echo "nameserver ${x}" >> "${tmpfile}" + done + + [[ -n ${search} ]] && echo "search ${search}" >> "${tmpfile}" + + system_dns_extra "${iface}" "${tmpfile}" + + mv "${tmpfile}" "${conffile}" +} + +system_ntp() { + local iface="$1" ifvar=$( bash_variable "$1" ) x + local conffile="${statedir}/${iface}/ntp.conf" tmpfile="${conffile}.$$" + local -a servers + + eval servers=( \"\$\{ntp_servers_${ifvar}\[\@\]\}\" ) + [[ -z ${servers} ]] && servers=( "${ntp_servers[@]}" ) + [[ -z ${servers} ]] && return 0 + + echo "# Generated by net-scripts for interface ${iface}" > "${tmpfile}" + chmod 644 "${tmpfile}" + + echo "restrict default noquery notrust nomodify" >> "${tmpfile}" + echo "restrict 127.0.0.1" >> "${tmpfile}" + + for x in ${servers[@]}; do + echo "restrict ${x} nomodify notrap noquery" >> "${tmpfile}" + echo "server ${x}" >> "${tmpfile}" + done + + echo "driftfile /var/lib/ntp/ntp.drift" >> "${tmpfile}" + echo "logfile /var/log/ntp.log" >> "${tmpfile}" + + mv "${tmpfile}" "${conffile}" +} + +system_nis() { + local iface="$1" ifvar=$( bash_variable "$1" ) domain x + local conffile="${statedir}/${iface}/yp.conf" tmpfile="${conffile}.$$" + local -a servers + + eval servers=( \"\$\{nis_servers_${ifvar}\[\@\]\}\" ) + [[ -z ${servers} ]] && servers=( "${nis_servers[@]}" ) + + eval domain=\"\$\{nis_domain_${ifvar}\}\" + [[ -z ${domain} ]] && domain="${nis_domain}" + + [[ -z ${servers} && -z ${domain} ]] && return 0 + + echo "# Generated by net-scripts for interface ${iface}" > "${tmpfile}" + chmod 644 "${tmpfile}" + + if [[ -n ${domain} ]]; then + /bin/hostname -y "${domain}" + if [[ -n ${servers} ]]; then + for x in ${servers}; do + echo "domain ${domain} server ${x}" >> "${tmpfile}" + done + else + echo "domain ${domain} broadcast" >> "${tmpfile}" + fi + else + for x in ${servers}; do + echo "ypserver ${x}" >> "${tmpfile}" + done + fi + + mv "${tmpfile}" "${conffile}" +} + +# bool system_post_start(char *iface) +# +# Configures the host system for dns, ntp and nis information +# Always returns 0 +system_pre_start() { + local iface="$1" + + system_dns "${iface}" + system_ntp "${iface}" + system_nis "${iface}" + + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/tuntap b/net-scripts/net.modules.d/tuntap new file mode 100644 index 0000000..22281e2 --- /dev/null +++ b/net-scripts/net.modules.d/tuntap @@ -0,0 +1,116 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +tunctl() { + LC_ALL=C /usr/bin/tunctl "$@" +} + +# char* tuntap_provides(void) +# +# Returns a string to change module definition for starting up +tuntap_provides() { + echo "tuntap" +} + +# void tuntap_depend(void) +# +# Sets up the dependancies for the module +tuntap_depend() { + after interface + before dhcp +} + +# bool tuntap_check_installed(void) +# +# Returns 1 if tuntap is installed, otherwise 0 +tuntap_check_installed() { + [[ -x /usr/bin/tunctl ]] && return 0 + ${1:-false} && eerror "For TunTap support, emerge sys-apps/usermode-utilities" + return 1 +} + +# bool tuntap_check_depends(void) +# +# Checks to see if we have the needed functions +tuntap_check_depends() { + local f + + for f in interface_exists interface_type; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "tuntap: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool tuntap_check_kernel(void) +# +# Checks to see if the tun is present - if not try and load it +# Returns 1 if there is a problem +tuntap_check_kernel() { + [[ -a /dev/net/tun ]] && return 0 + /sbin/modprobe tun && sleep 1 + [[ -a /dev/net/tun ]] && return 0 + eerror "TUN/TAP support is not present in this kernel" + return 1 +} + +# char* tuntap_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +tuntap_get_vars() { + echo "tunctl_$1" +} + +# bool tuntap_pre_start(char *iface) +# +# Create the device, give it the right perms +tuntap_pre_start() { + local iface="$1" opts ifvar=$( bash_variable "$1" ) + local itype=$( interface_type "${iface}" ) + + # Check that we are a valid tun/tap interface + # NOTE - the name can be anything as we define it + # but for simplicity in the config we require either + # tun or tap + [[ ${itype} != "tun" && ${itype} != "tap" ]] && return 0 + + tuntap_check_kernel || return 1 + + # Get our options + eval opts=\"\$\{tunctl_${ifvar}\}\" + + ebegin "Creating Tun/Tap interface ${iface}" + tunctl ${opts} -t "${iface}" >/dev/null + eend "$?" || return 1 + + return 0 +} + +# bool tuntap_stop(char *iface) +# +# Removes the device +tuntap_stop() { + local iface="$1" + + tuntap_check_installed || return 0 + interface_exists "${iface}" || return 0 + + # tunctl doesn't always error on on tun/tap + # interfaces (mainly aliases, etc) + if tunctl -d "${iface}" &>/dev/null ; then + interface_exists "${iface}" \ + || einfo "Destroyed Tun/Tap interface ${iface}" + fi + + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/udhcpc b/net-scripts/net.modules.d/udhcpc new file mode 100644 index 0000000..25596c5 --- /dev/null +++ b/net-scripts/net.modules.d/udhcpc @@ -0,0 +1,153 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +udhcpc() { + LC_ALL=C /sbin/udhcpc "$@" +} + +# char* udhcpc_provides(void) +# +# Returns a string to change module definition for starting up +udhcpc_provides() { + echo "dhcp" +} + +# void udhcpc_depend(void) +# +# Sets up the dependancies for the module +udhcpc_depend() { + after interface +} + +# bool udhcpc_check_installed(void) +# +# Returns 1 if udhcpc is installed, otherwise 0 +udhcpc_check_installed() { + [[ -x /sbin/udhcpc ]] && return 0 + ${1:-false} && eerror "For DHCP (udhcpc) support, emerge net-misc/udhcp" + return 1 +} + +# bool udhcpc_check_depends(void) +# +# Checks to see if we have the needed functions +udhcpc_check_depends() { + local f + + for f in interface_exists interface_get_address; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "udhcpc: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# char* udhcpc_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +udhcpc_get_vars() { + echo "udhcpc_$1 dhcp_$1" +} + +# bool udhcpc_stop(char *iface) +# +# Stops udhcpc running on an interface +# Return 1 if we fail to stop udhcpc (if it's running) otherwise 0 +udhcpc_stop() { + local iface="$1" pidfile="/var/run/udhcpc-$1.pid" d + + udhcpc_check_installed || return 0 + [[ ! -f ${pidfile} ]] && return 0 + + ebegin "Stopping udhcpc on ${iface}" + local pid=$( < "${pidfile}" ) e=true + + local ifvar=$( bash_variable "${iface}" ) + eval d=\" \$\{dhcp_${ifvar}\} \" + [[ ${d} == " " ]] && d=" ${dhcp} " + + if [[ ${d} == *" release "* ]]; then + kill -s USR2 "${pid}" &>/dev/null + [[ -f "/var/cache/dhcp-${iface}.lease" ]] \ + && rm "/var/cache/dhcp-${iface}.lease" + fi + + kill -s TERM "${pid}" &>/dev/null + + [[ -f ${pidfile} ]] && rm -f "${pidfile}" + + ${e} + eend "$?" + return "$?" +} + +# bool udhcpc_start(char *iface) +# +# Start DHCP on an interface by calling udhcpc $iface $options +# +# Returns 0 (true) when a DHCP address is obtained, otherwise 1 +udhcpc_start() { + local iface="$1" opts pidfile="/var/run/udhcpc-$1.pid" + local cachefile="/var/cache/dhcp-$1.lease" d + + interface_exists "${iface}" true || return 1 + + local ifvar=$( bash_variable "${iface}" ) opts hostname + eval opts=\"\$\{udhcpc_${ifvar}\}\" + + eval d=\" \$\{dhcp_${ifvar}\} \" + [[ ${d} == " " ]] && d=" ${dhcp} " + + if [[ ${d} != *" nosendhost "* ]]; then + if [[ ! " ${opts}" =~ " -([hH] |-hostname=)" ]]; then + local hostname=$( hostname ) + [[ -n ${hostname} && ${hostname} != "(none)" \ + && ${hostname} != "localhost" ]] \ + && opts="${opts} --hostname=${hostname}" + fi + fi + + # Bring up DHCP for this interface (or alias) + ebegin "Running udhcpc" + + # Stop any instance of udhcpc on this interface + udhcpc_stop "${interface}" + + # Try and load the cache if it exists + if [[ -f ${cachefile} ]]; then + if [[ " ${opts}" != *" --request="* && " ${opts} " != *" -r "* ]]; then + local x=$( < "${cachefile}" ) + [[ -n ${x} ]] && opts="${opts} --request=${x}" + fi + fi + + if [[ ${background} == "yes" ]]; then + eval udhcpc ${opts} --script="${MODULES_DIR}/helpers.d/udhcpc-wrapper" \ + --pidfile="${pidfile}" --interface="${iface}" &>/dev/null & + eend 0 + go_background + fi + + x=$( eval udhcpc ${opts} --now --pidfile="${pidfile}" \ + --interface="${iface}" \ + --script="${MODULES_DIR}/helpers.d/udhcpc-wrapper" 2>&1 \ + | egrep -v '^info,' ) + # We just check the last 5 letters + [[ ${x:((${#x} - 5)):5} == "bound" ]] + eend "$?" "${x}" || return 1 + + # DHCP succeeded, show address retrieved + local addr=$( interface_get_address "${iface}" ) + einfo "${iface} received address ${addr}" + + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/vlan b/net-scripts/net.modules.d/vlan new file mode 100644 index 0000000..a1966d5 --- /dev/null +++ b/net-scripts/net.modules.d/vlan @@ -0,0 +1,169 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +vconfig() { + LC_ALL=C /sbin/vconfig "$@" +} + +# char* vlan_provides(void) +# +# Returns a string to change module definition for starting up +vlan_provides() { + echo "vlan" +} + +# void vlan_depend(void) +# +# Sets up the dependancies for the module +vlan_depend() { + after interface + before dhcp arping +} + +# bool vlan_check_installed(void) +# +# Returns 1 if vconfig is installed, otherwise 0 +vlan_check_installed() { + [[ -x /sbin/vconfig ]] && return 0 + ${1:-false} && eerror "For VLAN (802.1q) support, emerge net-misc/vconfig" + return 1 +} + +# bool vlan_check_depends(void) +# +# Checks to see if we have the needed functions +vlan_check_depends() { + local f + + for f in iface_start iface_stop; do + [[ $( type -t "${f}" ) == function ]] && continue + eerror "vlan: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# char* vlan_get_vars(char *interface) +# +# Returns a string spaced with possible user set +# configuration variables +vlan_get_vars() { + echo "vlans_$1 iface_$1_vlans" +} + +# char* vlan_get_vlans(char *interface) +# +# Fetch the configured vlans for an interface. Outputs a space +# separated list on stdout. For example "eth0.1 eth0.2 eth0.3" +vlan_get_vlans() { + sed -n -e 's/^\(.*[0-9]\) \(.* \) .*'"$1"'$/\1/p' \ + /proc/net/vlan/config 2>/dev/null +} + +# bool vlan_check_kernel(void) +# +# Checks to see if the 802.1q module is present - if not try and load it +# Returns 1 if there is a problem +vlan_check_kernel() { + [[ -d /proc/net/vlan ]] && return 0 + /sbin/modprobe 8021q &>/dev/null + [[ -d /proc/net/vlan ]] && return 0 + eerror "VLAN (802.1q) support is not present in this kernel" + return 1 +} + +#bool vlan_pre_start(char *iface) +# +# Setup vconfig +vlan_pre_start() { + local iface="$1" opts i x e ifvar=$( bash_variable "$1" ) + + eval opts=( \"\$\{vconfig_${ifvar}\[@\]\}\" ) + [[ -z ${opts} ]] && return 0 + + vlan_check_kernel || return 1 + interface_exists "${iface}" || return 1 + + for (( i=0; i<${#opts[@]}; i++ )); do + if [[ ${opts[i]} == "set_name_type "* ]]; then + x="${opts[i]}" + else + x="${opts[i]/ / ${iface} }" + [[ ${x} == "${opts[i]}" ]] && x="${x} ${iface}" + fi + e=$( vconfig ${x} 2>&1 1>/dev/null ) + [[ -z ${e} ]] && continue + eerror "vconfig ${x}" + eerror "${e}" + return 1 + done + + return 0 +} + +# bool vlan_post_start(char *iface) +# +# Starts VLANs for a given interface +# +# Always returns 0 (true) +vlan_post_start() { + local iface="$1" vlan vlans vlans_old e ifname ifvar=$( bash_variable "$1" ) + + eval vlans=\"\$\{vlans_${ifvar}\}\" + + # BACKWARD COMPATIBILITY: check for old vlan variable name + eval vlans_old=\"\$\{iface_${ifvar}_vlans\}\" + [[ -n ${vlans_old} && -z ${vlans} ]] && vlans="${vlans_old}" + + [[ -z ${vlans} ]] && return 0 + + vlan_check_kernel || return 1 + interface_exists "${iface}" true || return 1 + + # Start vlans for this interface + for vlan in ${vlans}; do + einfo "Adding VLAN ${vlan} to ${iface}" + e=$( vconfig add "${iface}" "${vlan}" 2>&1 1>/dev/null ) + if [[ -n ${e} ]] ; then + eend 1 "${e}" + continue + fi + eend 0 + + # We need to work out the interface name of our new vlan id + ifname=$( \ + sed -n -e 's/^\([^ \t]*\) *| '"${vlan}"' *| .*'"${iface}"'$/\1/p' \ + /proc/net/vlan/config + ) + iface_start "${ifname}" + done + + return 0 +} + +# bool vlan_pre_stop(char *iface) +# +# Stops VLANs for a given interface +# +# Always returns 0 (true) +vlan_pre_stop() { + local iface="$1" vlan + + vlan_check_installed || return 0 + + for vlan in $( vlan_get_vlans "${iface}" ); do + einfo "Removing VLAN ${vlan##*.} from ${iface}" + iface_stop "${vlan}" + vconfig rem "${vlan}" >/dev/null + done + + return 0 +} + +# vim:ts=4 diff --git a/net-scripts/net.modules.d/wpa_supplicant b/net-scripts/net.modules.d/wpa_supplicant new file mode 100644 index 0000000..acedeab --- /dev/null +++ b/net-scripts/net.modules.d/wpa_supplicant @@ -0,0 +1,365 @@ +#!/bin/bash +# Copyright (c) 2004-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +wpa_supplicant() { + LC_ALL=C /sbin/wpa_supplicant "$@" +} + +wpa_cli() { + LC_ALL=C /bin/wpa_cli "$@" +} + +# char* wpa_supplicant_provides(void) +# +# Returns a string to change module definition for starting up +wpa_supplicant_provides() { + echo "wireless" +} + +# void wpa_supplicant_depend(void) +# +# Sets up the dependancies for the module +wpa_supplicant_depend() { + after macnet + before interface +} + +# bool wpa_supplicant_check_installed(void) +# +# Returns 0 if wpa_supplicant is installed, otherwise 1 +wpa_supplicant_check_installed() { + local report="${1:-false}" installed="0" + if [[ ! -x /sbin/wpa_supplicant ]]; then + installed="1" + ${report} && eerror "For WPA support (wpa_supplicant) support, emerge net-wireless/wpa_supplicant" + fi + if [[ ! -e /proc/net/wireless ]]; then + installed="1" + if ${report} ; then + eerror "wpa_supplicant requires wireless support" + eerror "(CONFIG_NET_WIRELESS=y) enabled in the kernel" + fi + fi + if [[ ! -e /proc/net/packet ]]; then + installed="1" + if ${report} ; then + eerror "wpa_supplicant requires Packet Socket" + eerror "(CONFIG_PACKET=y) enabled in the kernel" + fi + fi + return "${installed}" +} + +# bool wpa_supplicant_check_depends(void) +# +# Checks to see if we have the needed functions +wpa_supplicant_check_depends() { + local f + + for f in interface_exists; do + [[ $( type -t "${f}" ) == "function" ]] && continue + eerror "wpa_supplicant: missing required function ${f}\n" + return 1 + done + + return 0 +} + +# bool wpa_supplicant_check_extensions(char *interface) +# +# Checks to see if wireless extensions are enabled on the interface +wpa_supplicant_check_extensions() { + [[ ! -e /proc/net/wireless ]] && return 1 + grep -q "^[ \t]*$1:[ \t]" /proc/net/wireless +} + +# char* wpa_supplicant_get_essid(char *interface) +# +# Gets the current ESSID of iface +wpa_supplicant_get_essid() { + local i essid + + for (( i=0; i<5; i++ )); do + essid=$( wpa_cli -i"$1" status | sed -n -e 's/^ssid=//p' ) + if [[ -n ${essid} ]]; then + echo "${essid}" + return 0 + fi + sleep 1 + done + + return 1 +} + +# char* wpa_supplicant_get_ap_mac_address(char *interface) +# +# Returns the MAC address of the Access Point +# the interface is connected to +wpa_supplicant_get_ap_mac_address() { + wpa_cli -i"$1" status | sed -n -e 's/^bssid=\([^=]\+\).*/\U\1/p' +} + +# bool wpa_supplicant_associated(char *interface) +# +# Returns 0 if we're associated correctly or 1 if not +# Note that just because we are associated does not mean we are using the +# correct encryption keys +# We only need this for wpa_supplicant-0.3.x +wpa_supplicant_associated() { + local -a status=( "$( wpa_cli -i"$1" status | sed -n -e 's/^\(key_mgmt\|wpa_state\|EAP state\)=\([^=]\+\).*/\U\2/p' )" ) + + case "${status[0]}" in + "NONE") [[ ${status[1]} == "ASSOCIATED" ]] ;; + "IEEE 802.1X (no WPA)") [[ ${status[2]} == "SUCCESS" ]] ;; + *) [[ ${status[1]} == "COMPLETED" ]] ;; + esac + + return $? +} + +# void wpa_supplicant_kill(char *interface, bool report) +# +# Kills any existing wpa_supplicant process on the interface +wpa_supplicant_kill() { + local iface="$1" report="${2:-false}" pidfile + + # Shutdown wpa_cli first, if it's running + # This is important as future versions of wpa_supplicant + # may send a disconnect message to wpa_cli when it shutsdown + pidfile="/var/run/wpa_cli-${iface}.pid" + if ! clean_pidfile "${pidfile}" ; then + ${report} && ebegin "Stopping wpa_cli on ${iface}" + start-stop-daemon --stop --exec /bin/wpa_cli \ + --pidfile "${pidfile}" + ${report} && eend "$?" + fi + + # Now shutdown wpa_supplicant + pidfile="/var/run/wpa_supplicant-${iface}.pid" + if ! clean_pidfile "${pidfile}" ; then + ${report} && ebegin "Stopping wpa_supplicant on ${iface}" + start-stop-daemon --stop --exec /sbin/wpa_supplicant \ + --pidfile "${pidfile}" + ${report} && eend "$?" + else + # Support wpa_supplicant-0.3.x + local pid=$( pgrep -f '^/sbin/wpa_supplicant .* -i'"${iface}"'[ ]*$' ) + if [[ -n ${pid} ]]; then + ${report} && ebegin "Stopping wpa_supplicant on ${iface}" + kill -s TERM "${pid}" + ${report} && eend 0 + fi + fi + + # If wpa_supplicant exits uncleanly, we need to remove the stale dir + [[ -S "/var/run/wpa_supplicant/${iface}" ]] \ + && rm -f "/var/run/wpa_supplicant/${iface}" +} + +# bool wpa_supplicant_associate(char *interface) +# +# Returns 0 if wpa_supplicant associates and authenticates to an AP +# otherwise, 1 +wpa_supplicant_associate() { + local iface="$1" ifvar=$( bash_variable "$1" ) timeout i + eval timeout=\"\$\{associate_timeout_${ifvar}\}\" + [[ -z ${timeout} ]] && eval timeout=\"\$\{wpa_timeout_${ifvar}:-60\}\" + + if [[ ${timeout} == "0" ]]; then + ewarn "WARNING: infinite timeout set for association on ${iface}" + elif [[ ${timeout} -lt 0 ]]; then + ewarn "WARNING: negative timeout set for ${iface}" + exit 0 + fi + + while true ; do + if ${action} ; then + service_started "net.${iface}" && return 0 + else + if ! wpa_cli -i"${iface}" status &>/dev/null ; then + eend 1 "wpa_supplicant has exited unexpectedly" + return 1 + fi + wpa_supplicant_associated "${iface}" && return 0 + fi + sleep 1 + (( i++ )) + [[ ${i} == "${timeout}" || ${i} -gt "${timeout}" ]] && break + done + + # Spit out an appropriate error + if [[ ${background} != "yes" ]]; then + if ${action} ; then + eend 1 "Failed to configure ${iface} in the background" + else + eend 1 "Timed out" + fi + fi + + # exit without error with wpa_supplicant-0.4.x as we may get kickstarted + # when an AP comes in range + ${action} && exit 0 + + # Kill wpa_supplicant for 0.3.x + wpa_supplicant_kill "${iface}" + return 1 +} + +# bool wpa_supplicant_pre_start(char *interface) +# +# Start wpa_supplicant on an interface and wait for association +# Returns 0 (true) when successful, non-zero otherwise +wpa_supplicant_pre_start() { + local iface="$1" opts timeout action=false + local cfgfile="/etc/wpa_supplicant.conf" + local actfile="/sbin/wpa_cli.action" + + # We don't configure wireless if we're being called from + # the background + if ${IN_BACKGROUND} ; then + ESSID=$( wpa_supplicant_get_essid "${iface}" ) + ESSIDVAR=$( bash_variable "${ESSID}" ) + save_options "ESSID" "${ESSID}" + return 0 + fi + + save_options "ESSID" "" + + # We only work on wirelesss interfaces + wpa_supplicant_check_extensions "${iface}" || return 0 + + # Kill off any existing wpa_supplicant on this interface + # This is so we can re-read the configuration file and clean any stale + # directories + wpa_supplicant_kill "${iface}" true + + # Check for rf_kill - only ipw supports this at present, but other + # cards may in the future + if [[ -e "/sys/class/net/${iface}/device/rf_kill" ]]; then + if [[ $( < "/sys/class/net/${iface}/device/rf_kill" ) != 0 ]]; then + eerror "Wireless radio has been killed for interface ${iface}" + return 1 + fi + fi + + # If wireless-tools is installed, try and apply our user config + # This is needed for some drivers - such as hostap because they start + # the card in Master mode which causes problems with wpa_supplicant. + if [[ $( type -t iwconfig_defaults ) == "function" ]]; then + iwconfig_defaults "${iface}" + iwconfig_user_config "${iface}" + fi + + ebegin "Starting wpa_supplicant on ${iface}" + + if [[ ! -f ${cfgfile} ]]; then + eend 1 "configuration file ${cfgfile} not found!" + return 1 + fi + + local ctrl_dir=$( sed -n -e 's/[ \t]*#.*//g;s/[ \t]*$//g;s/^ctrl_interface=//p' "${cfgfile}" ) + if [[ ${ctrl_dir} != "/var/run/wpa_supplicant" ]]; then + eerror "${cfgfile} must set" + eerror " ctrl_interface=/var/run/wpa_supplicant" + eend 1 + return 1 + fi + + local ifvar=$( bash_variable "${iface}" ) + eval opts=\" \$\{wpa_supplicant_${ifvar}\}\" + [[ ${opts} != *" -D"* ]] \ + && ewarn "wpa_supplicant_${ifvar} does not define a driver" + + # Some drivers require the interface to be up + interface_up "${iface}" + + version=$( wpa_cli -v | sed -n -e 's/wpa_cli v//p' ) + version=( ${version//./ } ) + (( version = version[0] * 1000 + version[1] * 100 + version[2] )) + + # wpa_supplicant 0.4.0 and greater supports wpa_cli actions + # This is very handy as if and when different association mechanisms are + # introduced to wpa_supplicant we don't have to recode for them as + # wpa_cli is now responsible for informing us of success/failure. + # The downside of this is that we don't see the interface being configured + # for DHCP/static. + if [[ ${version} -gt 399 && -x ${actfile} ]]; then + opts="${opts} -W -P/var/run/wpa_supplicant-${iface}.pid" + action=true + [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && background=no + fi + + start-stop-daemon --start --exec /sbin/wpa_supplicant \ + -- ${opts} -B -c/etc/wpa_supplicant.conf -i"${iface}" + eend "$?" || return 1 + + # Starting wpa_supplication-0.4.0, we can get wpa_cli to + # start/stop our scripts from wpa_supplicant messages + if ${action} ; then + mark_service_inactive "net.${iface}" + ebegin "Starting wpa_cli on ${iface}" + start-stop-daemon --start --exec /bin/wpa_cli \ + -- -a"${actfile}" -i"${iface}" \ + -P"/var/run/wpa_cli-${iface}.pid" -B + eend "$?" || return 1 + fi + + # Background wpa_supplication if required + if [[ ${background} == "yes" ]]; then + if ! ${action} ; then + wpa_supplicant_associate "${iface}" \ + && export IN_BACKGROUND=true \ + && /etc/init.d/net.${iface} start >/dev/null & + fi + go_background + fi + + eindent + veinfo "Waiting for association" + eend 0 + + wpa_supplicant_associate "${iface}" || return 1 + + # Set ESSID for essidnet and report + ESSID=$( wpa_supplicant_get_essid "${iface}" ) + ESSIDVAR=$( bash_variable "${ESSID}" ) + save_options "ESSID" "${ESSID}" + + local -a status=( "$( wpa_cli -i${iface} status | sed -n -e 's/^\(bssid\|pairwise_cipher\|key_mgmt\)=\([^=]\+\).*/\U\2/p' | tr '[:lower:]' '[:upper:]' )" ) + einfo "${iface} connected to \"${ESSID//\\\\/\\\\}\" at ${status[0]}" + + if [[ ${status[2]} == "NONE" ]]; then + if [[ ${status[1]} == "NONE" ]]; then + ewarn "not using any encryption" + else + veinfo "using ${status[1]}" + fi + else + veinfo "using ${status[2]}/${status[1]}" + fi + eoutdent + + if ${action} ; then + local addr=$( interface_get_address "${iface}" ) + einfo "${iface} configured with address ${addr}" + exit 0 + fi + + return 0 +} + +# bool wpa_supplicant_post_stop(char *iface) +# +# Stops wpa_supplicant on an interface +# Returns 0 (true) when successful, non-zero otherwise +wpa_supplicant_post_stop() { + ! ${IN_BACKGROUND} && wpa_supplicant_kill "$1" true + return 0 +} + +# vim:ts=4 diff --git a/sbin/MAKEDEV b/sbin/MAKEDEV index 54901b2..832965d 100755 --- a/sbin/MAKEDEV +++ b/sbin/MAKEDEV @@ -1,6 +1,5 @@ #! /bin/sh - - -RCSID='$Id: MAKEDEV 560 2004-09-19 05:39:28Z vapier $' +# $Id: MAKEDEV 1421 2005-08-23 23:56:23Z vapier $ #---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---# # Customisation: @@ -14,9 +13,8 @@ RCSID='$Id: MAKEDEV 560 2004-09-19 05:39:28Z vapier $' private=" root root 0600" system=" root root 0660" kmem=" root kmem 0640" - tty=" root tty 0660" # Perms was 0666 + tty=" root tty 0666" cons=" root tty 0600" - vcs=" root root 0600" dialout=" root dialout 0660" dip=" root dip 0660" mouse=" root root 0660" @@ -28,9 +26,8 @@ printer=" root lp 0660" tape=" root tape 0660" audio=" root audio 0660" video=" root video 0660" - fb=" root video 0620" - ibcs2=" root root 0660" # Perms was 0666 -scanner=" root root 0660" # Perms was 0666 + ibcs2=" root root 0666" +scanner=" root root 0666" coda=" root root 0600" ipsec=" root root 0200" readable=" root root 0444" @@ -47,20 +44,40 @@ major_lp=6 #---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---# +# try to do the right things if udev is running +if [ "$WRITE_ON_UDEV" ]; then + : +elif [ -d /dev/.static/dev/ ] && [ "`pwd`" = /dev ] && [ -e /proc/mounts ] \ + && grep -qE '^[^ ]+ /dev/\.static/dev' /proc/mounts; then + cd /dev/.static/dev/ +elif [ -d /.dev/ ] && [ "`pwd`" = /dev ] && [ -e /proc/mounts ] \ + && grep -qE '^[^ ]+ /\.dev' /proc/mounts; then + cd /.dev/ +elif [ -d .udevdb/ ] && [ "`pwd`" = /dev ]; then + echo ".udevdb presence implies active udev. Aborting MAKEDEV invocation." + # use exit 0, not 1, so postinst scripts don't fail on this + exit 0 +fi + +#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---# + # don't stomp on devfs users if [ -c .devfsd ] then - echo ".devfsd presence implies active DevFS. Aborting MAKEDEV invocation." - # use exit 0, not 1, so postinst scripts don't fail on this - exit 0 + echo ".devfsd presence implies active DevFS. Aborting MAKEDEV invocation." + # use exit 0, not 1, so postinst scripts don't fail on this + exit 0 fi +#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---# -# make sure we are not in / -if [ "`pwd`" = "/" ]; then - echo "Running MAKEDEV in your root filesystem is a VERY BAD IDEA." - exit 0 -fi +# don't stomp on non-Linux users +if [ "$(uname -s)" != "Linux" ] +then + echo "Results undefined on non-Linux systems, aborting MAKEDEV invocation." + # use exit 0, not 1, so postinst scripts don't fail on this + exit 0 +fi #---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---# @@ -85,7 +102,8 @@ done if [ "$opt_V" ] then - echo "$RCSID" + echo "This is MAKEDEV based on Debian's makedev_2.3.1-78." + echo "See the MAKEDEV(8) manpage for more information." exit 0 fi @@ -93,23 +111,39 @@ opts="${opt_n:+-n} ${opt_v:+-v} ${opt_d:+-d}" #---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---# +devicename () { # translate device names to something safe + echo "$*" | sed -e 's/[^A-Za-z0-9_]/_/g' +} + makedev () { # usage: makedev name [bcu] major minor owner group mode if [ "$opt_v" ] then if [ "$opt_d" ] then echo "delete $1" - else echo "create $1 $2 $3 $4 $5:$6 $7" + else echo "create $1 $2 $3 $4 $5:$6 $7" fi fi + # missing parameters are a bug - bail - should we do an exit 1 here? + case :$1:$2:$3:$4:$5:$6:$7: in + *::*) echo "Warning: MAKEDEV $@ is missing parameter(s)." >&2;; + esac if [ ! "$opt_n" ] - then if [ "$opt_d" ] + then + if [ "$opt_d" ] then rm -f $1 else rm -f $1- - mknod $1- $2 $3 $4 && - chown $5:$6 $1- && - chmod $7 $1- && - mv $1- $1 + if mknod $1- $2 $3 $4 && + chown $5:$6 $1- && + chmod $7 $1- && + mv $1- $1 + then + : # it worked + else + # Didn't work, clean up any mess... + echo "makedev $@: failed" + rm -f $1- + fi fi fi } @@ -142,13 +176,13 @@ strip () { eval echo "\${1% $2 *} \${1#* $2 }" } first () { - eval echo "\${1:0:1}" + echo "${1%%?}" } second () { - eval echo "\${1:1:1}" + echo "${1##?}" } substr () { - echo $1 | cut -c $2 + echo $1 | dd bs=1 count=1 skip=$(( $2 - 1 )) 2> /dev/null } #---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---# @@ -159,14 +193,15 @@ then echo "$0: warning: can't read $procfs/devices" >&2 else exec 3<$procfs/devices - while read major device <&3 + while read major device extra <&3 do device=`echo $device | sed 's#/.*##'` case "$major" in Character|Block|'') ;; *) - eval "major_${device/-/_}=$major" + safedevname=`devicename $device` + eval "major_$safedevname=$major" devices="$devices $device" ;; esac @@ -176,11 +211,12 @@ fi Major () { device=$2 + devname=`devicename $1` if [ "$opt_d" ] then echo -1 # don't care else - eval echo \${major_${1/-/_}:-\${device:?\"unknown major number for $1\"}} + eval echo \${major_$devname:-\${device:?\"unknown major number for $1\"}} fi } @@ -199,6 +235,10 @@ cvt () { ide3) echo hdg hdh ;; ide4) echo hdi hdj ;; ide5) echo hdk hdl ;; + ide6) echo hdm hdn ;; + ide7) echo hdo hdp ;; + ide8) echo hdq hdr ;; + ide9) echo hds hdt ;; sd) echo sda sdb sdc sdd ;; dasd) (for d in a b c d e f g h i j k l m \ n o p q r s t u v w x y z ; do @@ -242,18 +282,24 @@ cvt () { microcode) echo microcode ;; ipmi|ipmikcs) echo ipmi ;; fb) echo fb ;; - nb) echo nb0 nb1 ;; + nb|drbd) echo nb0 nb1 nb2 nb3 nb4 nb5 nb6 nb7;; netlink) echo netlink ;; tap) echo netlink ;; hamradio) echo hamradio ;; snd) ;; ptm) ;; pts) ;; - ttyS) echo ttyS0 ttyS1 ttyS2 ttyS3 ;; + ttyB) (for l in 0 1 2 3 4 5 6 7 ; do + echo -n ttyB$l " " + done) ; echo + ;; + ttyS) echo ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 ;; ttyI) echo ttyI0 ttyI1 ttyI2 ttyI3 ;; - ircomm|irlpt) echo irda ;; + ircomm|irlpt) irda ;; ppp) echo ppp ;; usb) echo usb ;; + dpt_i2o) echo dpti ;; + bluetooth) echo bluetooth ;; lvm) ;; # taken care of by LVM userspace tools ramdisk) echo ram ;; *) echo "$0: don't know what \"$1\" is" >&2 ;; @@ -262,70 +308,28 @@ cvt () { done } -for arg +get_arch() { + local a=`uname -m` + case `uname -m` in + arm*) echo arm;; + i?86) echo i386;; + ppc*) echo powerpc;; + s390*) echo s390;; + sh*) echo sh;; + x86_64) echo i386;; + # alpha|hppa|ia64|m68k|mips|sparc + *) echo $a;; + esac +} + +for arg in $* do # case `cvt $arg` in case $arg in generic) - if [ -n "`which dpkg 2> /dev/null`" ] - then - # pick the right generic-<arch> using dpkg's knowledge - case `dpkg --print-installation-architecture` in - alpha) - $0 $opts generic-alpha - ;; - arm) - $0 $opts generic-arm - ;; - hppa) - $0 $opts generic-hppa - ;; - i386) - $0 $opts generic-i386 - ;; - ia64) - $0 $opts generic-ia64 - ;; - m68k) - $0 $opts generic-m68k - ;; - mips) - $0 $opts generic-mips - ;; - mipsel) - $0 $opts generic-mipsel - ;; - powerpc) - $0 $opts generic-powerpc - ;; - s390) - $0 $opts generic-s390 - ;; - sparc) - $0 $opts generic-sparc - ;; - *) - echo "$0: no support for generic on this arch" >&2 - exit 1 - ;; - esac - else - $0 $opts std - $0 $opts fd - $0 $opts fd0 fd1 - $0 $opts hda hdb - $0 $opts xda xdb - $0 $opts sda sdb - $0 $opts pty - $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 - $0 $opts busmice - $0 $opts lp - $0 $opts par - fi + $0 $opts generic-`get_arch` ;; generic-alpha) - export MDARCH="alpha" $0 $opts std $0 $opts fd $0 $opts fd0 fd1 @@ -337,15 +341,15 @@ do $0 $opts sg $0 $opts pty $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 $0 $opts busmice $0 $opts lp $0 $opts par $0 $opts audio $0 $opts fb + $0 $opts dac960 ;; generic-arm) - export MDARCH="arm" $0 $opts std $0 $opts fd $0 $opts fd0 fd1 @@ -357,25 +361,27 @@ do $0 $opts sg $0 $opts pty $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 $0 $opts busmice + makedev sunmouse c 10 6 $mouse $0 $opts lp $0 $opts par $0 $opts audio $0 $opts fb ;; generic-hppa) - export MDARCH="hppa" $0 $opts std $0 $opts fd $0 $opts fd0 fd1 + $0 $opts hda hdb hdc hdd $0 $opts sda sdb sdc sdd $0 $opts scd0 scd1 $0 $opts st0 st1 $0 $opts sg $0 $opts pty $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 + $0 $opts ttyB0 ttyB1 ttyB2 ttyB3 ttyB4 ttyB5 ttyB6 ttyB7 $0 $opts busmice $0 $opts lp $0 $opts par @@ -384,7 +390,6 @@ do $0 $opts rtc ;; generic-i386) - export MDARCH="i386" $0 $opts std $0 $opts fd $0 $opts fd0 fd1 @@ -396,23 +401,23 @@ do $0 $opts sg $0 $opts pty $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 $0 $opts busmice + $0 $opts input $0 $opts lp $0 $opts par $0 $opts audio $0 $opts fb $0 $opts isdn-io eda edb sonycd mcd mcdx cdu535 - $0 $opts optcd sjcd cm206cd gscd - $0 $opts lmscd sbpcd aztcd bpcd dac960 ida ataraid cciss + $0 $opts optcd sjcd cm206cd gscd + $0 $opts lmscd sbpcd aztcd bpcd dac960 dpti ida ataraid cciss + $0 $opts i2o.hda i2o.hdb i2o.hdc i2o.hdd ;; generic-ia64) - export MDARCH="ia64" $0 $opts std $0 $opts fd $0 $opts fd0 fd1 $0 $opts hda hdb hdc hdd - $0 $opts xda xdb $0 $opts sda sdb sdc sdd $0 $opts scd0 scd1 $0 $opts st0 st1 @@ -421,6 +426,7 @@ do $0 $opts console $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 ttyS5 $0 $opts busmice + $0 $opts input $0 $opts lp $0 $opts par $0 $opts audio @@ -428,17 +434,17 @@ do $0 $opts efirtc ;; generic-m68k) - export MDARCH="m68k" $0 $opts std $0 $opts fd $0 $opts fd0 fd1 $0 $opts hda hdb hdc hdd $0 $opts sda sdb sdc sdd + $0 $opts scd0 scd1 $0 $opts sg $0 $opts ada adb adc add ade adf $0 $opts pty $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS5 + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 ttyS5 $0 $opts m68k-mice $0 $opts lp $0 $opts par @@ -447,7 +453,6 @@ do $0 $opts fb ;; generic-mips) - export MDARCH="mips" $0 $opts std $0 $opts fd $0 $opts fd0 fd1 @@ -458,7 +463,7 @@ do $0 $opts sg $0 $opts pty $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 $0 $opts lp $0 $opts par $0 $opts audio @@ -466,7 +471,6 @@ do $0 $opts busmice ;; generic-mipsel) - export MDARCH="mipsel" $0 $opts std $0 $opts fd $0 $opts fd0 fd1 @@ -477,7 +481,7 @@ do $0 $opts sg $0 $opts pty $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 $0 $opts lp $0 $opts par $0 $opts audio @@ -485,7 +489,6 @@ do $0 $opts rtc ;; generic-powerpc) - export MDARCH="powerpc" $0 $opts std $0 $opts fd $0 $opts fd0 fd1 @@ -496,7 +499,7 @@ do $0 $opts sg $0 $opts pty $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 $0 $opts busmice $0 $opts m68k-mice $0 $opts input @@ -510,7 +513,6 @@ do $0 $opts isdn-io ;; generic-s390) - export MDARCH="s390" $0 $opts std $0 $opts fd $0 $opts dasda dasdb dasdc dasdd dasde dasdf dasdg dasdh \ @@ -521,10 +523,29 @@ do $0 $opts consoleonly $0 $opts rtc ;; + generic-sh) + $0 $opts std + $0 $opts fd + $0 $opts fd0 fd1 + $0 $opts hda hdb + $0 $opts sda sdb sdc sdd + $0 $opts scd0 scd1 + $0 $opts st0 st1 + $0 $opts sg + $0 $opts pty + $0 $opts console + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 + $0 $opts ttySC0 ttySC1 ttySC2 ttySC3 + $0 $opts lp + $0 $opts par + $0 $opts audio + $0 $opts fb + $0 $opts rtc + ;; generic-sparc) - export MDARCH="sparc" $0 $opts std - $0 $opts fd0-bare fd1-bare + $0 $opts fd + $0 $opts fd0 fd1 $0 $opts hda hdb hdc hdd $0 $opts sda sdb sdc sdd $0 $opts scd0 scd1 @@ -532,17 +553,16 @@ do $0 $opts sg $0 $opts pty $0 $opts console - $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 + $0 $opts ttyS0 ttyS1 ttyS2 ttyS3 ttyS4 $0 $opts busmice $0 $opts fb $0 $opts rtc makedev kbd c 11 0 $cons makedev sunmouse c 10 6 $mouse symlink mouse sunmouse - makedev openprom c 10 139 $mouse + makedev openprom c 10 139 root root 0664 ;; generic-vserver) - export MDARCH="vserver" makedev null c 1 3 $public makedev zero c 1 5 $public makedev full c 1 7 $public @@ -558,6 +578,10 @@ do $0 $opts fd $0 $opts ptmx ;; + generic-*) + echo "$0: no support for generic on this arch" >&2 + exit 1 + ;; local) $0.local $opts ;; @@ -580,7 +604,7 @@ do $0 $opts bc ;; scc) - for unit in 0 1 2 3 4 5 6 7 + for unit in 0 1 2 3 4 5 6 7 do makedev scc$unit c 34 $unit $system done @@ -611,22 +635,22 @@ do makedev initrd b 1 250 $disk ;; raw) - makedev raw c 162 0 $disk - symlink rawctl raw + makedev rawctl c 162 0 $disk + mkdir -p raw for i in 1 2 3 4 5 6 7 8; do - makedev raw$i c 162 $i $disk + makedev raw/raw$i c 162 $i $disk done ;; consoleonly) makedev tty0 c 4 0 $cons # new kernels need a device, old ones a symlink... sigh - kern_rev1=`uname -r | awk -F'.' '{print $1}'` - kern_rev2=`uname -r | awk -F'.' '{print $2}'` + kern_rev1=`uname -r | sed -e 's@^\([^.]*\)\..*@\1@'` + kern_rev2=`uname -r | sed -e 's@^[^.]*\.\([^.]*\)\..*@\1@'` if [ $kern_rev1 -gt 2 ] then makedev console c 5 1 $cons else - if [ $kern_rev1 -eq 2 -a $kern_rev2 -ge 1 ] + if [ $kern_rev1 -eq 2 ] && [ $kern_rev2 -ge 1 ] then makedev console c 5 1 $cons else @@ -637,34 +661,22 @@ do console) $0 $opts consoleonly major=`Major vcs 7` # not fatal - [ "$major" ] && makedev vcs0 c $major 0 $vcs + [ "$major" ] && makedev vcs0 c $major 0 $cons symlink vcs vcs0 - [ "$major" ] && makedev vcsa0 c $major 128 $vcs + [ "$major" ] && makedev vcsa0 c $major 128 $cons symlink vcsa vcsa0 # individual vts line=1 - while [ $line -le $MAXVT -a $line -le 63 ] + while [ $line -le $MAXVT ] && [ $line -le 63 ] do - makedev tty$line c 4 $line $tty - [ "$major" ] && makedev vcs$line c $major $line $vcs - [ "$major" ] && makedev vcsa$line c $major `math $line + 128` $vcs + makedev tty$line c 4 $line $cons + [ "$major" ] && makedev vcs$line c $major $line $cons + [ "$major" ] && makedev vcsa$line c $major `math $line + 128` $cons line=`math $line + 1` done ;; adb) - myarch= - - if [ -n "`which dpkg 2> /dev/null`" ] - then - # pick the right arch device using dpkg's knowledge - myarch="`dpkg --print-installation-architecture`" - - elif [ -n "${MDARCH}" ] - then - myarch="${MDARCH}" - fi - - case $myarch in + case `get_arch` in powerpc) # ADB bus devices (char) makedev adb c 56 0 $mouse @@ -688,18 +700,35 @@ do raw1394) makedev raw1394 c 171 0 $disk ;; + video1394) + rm -f video1394 + mkdir -p video1394 + for i in `seq 0 15` + do + makedev video1394/$i c 171 `math 16 + $i` $video + done + ;; nvram) makedev nvram c 10 144 $mouse ;; tty[1-9]|tty[1-5][0-9]|tty[6][0-3]) line=`suffix $arg tty` - makedev tty$line c 4 $line $tty + makedev tty$line c 4 $line $cons ;; ttyS[0-9]|ttyS[1-5][0-9]|ttyS[6][0-3]) line=`suffix $arg ttyS` minor=`math 64 + $line` makedev ttyS$line c 4 $minor $dialout ;; + ttySC[0-3]) + line=`suffix $arg ttySC` + minor=`math 8 + $line` + makedev ttySC$line c 204 $minor $dialout + ;; + ttyB[0-7]) + minor=`suffix $arg ttyB` + makedev ttyB$minor c 11 $minor $dialout + ;; pty[a-ep-z]) bank=`suffix $arg pty` base=`index pqrstuvwxyzabcde $bank` @@ -727,7 +756,7 @@ do major1=`Major ttyC 19` || continue #major2=`Major cub 20` || continue for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \ - 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 do makedev ttyC$i c $major1 $i $dialout #makedev cub$i c $major2 $i $dialout @@ -916,31 +945,27 @@ do ;; ubd) major=98 - minor=0 - until [ $minor -gt 255 ] + for devicenum in 0 1 2 3 4 5 6 7 do - makedev ubd$minor b $major $minor $disk - minor=`math $minor + 1` + device=ubd`substr abcdefgh $(($devicenum + 1))` + baseminor=`math $devicenum \* 16` + makedev $device b $major $baseminor $disk + for partition in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + do + minor=`math $baseminor + $partition` + makedev $device$partition b $major $minor $disk + done done ;; fb) for i in 0 1 2 3 4 5 6 7 do - makedev fb$i c 29 `math 32 \* $i` $fb - makedev fb${i}current c 29 `math 32 \* $i` $fb - makedev fb${i}autodetect c 29 `math 32 \* $i + 1` $fb + makedev fb$i c 29 $i $video done ;; fb[0-7]) dev=`suffix $arg fb` - base=`math 32 \* $dev` - makedev fb$dev c 29 $base $fb - makedev fb${dev}current c 29 $base $fb - makedev fb${dev}autodetect c 29 `math $base + 1` $fb - for i in 0 1 2 3 4 5 6 7 - do - makedev fb${dev}user$i c 29 `math $base + 24 + $i` $fb - done + makedev fb$dev c 29 $dev $video ;; netlink|tap|tap[0-9]|tap1[0-5]) makedev route c 36 0 $coda @@ -951,6 +976,10 @@ do makedev tap$i c 36 `math $i + 16` $coda done ;; + tun) + mkdir -p net + makedev net/tun c 10 200 $system + ;; lp) major=`Major lp 6` || continue makedev ${arg}0 c $major 0 $printer @@ -1010,7 +1039,7 @@ do major=`Major $arg 10` || continue makedev $arg c $major 175 $video ;; - intel_rng) + hwrng) major=`Major $arg 10` || continue makedev $arg c $major 183 $private ;; @@ -1035,6 +1064,9 @@ do makedev irlpt$i c 161 `math $i + 16` $printer done ;; + irnet) + makedev irnet c 10 187 $system + ;; misc) major=`Major mouse 10` || continue makedev logibm c $major 0 $mouse @@ -1057,7 +1089,7 @@ do makedev exttrp c $major 133 $mouse makedev apm_bios c $major 134 $mouse makedev rtc c $major 135 $mouse - makedev openprom c $major 139 $mouse + makedev openprom c $major 139 root root 0664 makedev relay8 c $major 140 $mouse makedev relay16 c $major 141 $mouse makedev msr c $major 142 $mouse @@ -1068,18 +1100,31 @@ do makedev mergemem c $major 153 $mouse makedev pmu c $major 154 $mouse ;; - smapi|thinkpad) + pmu) + major=`Major mouse 10` || continue + makedev pmu c $major 154 $mouse + ;; + thinkpad) major=`Major mouse 10` || continue - makedev smapi c $major 170 $mouse - symlink thinkpad smapi + mkdir -p thinkpad + makedev thinkpad/thinkpad c $major 170 $mouse ;; - rtc) + rtc) major=`Major mouse 10` || continue makedev rtc c $major 135 $mouse ;; efirtc) major=`Major mouse 10` || continue makedev efirtc c $major 136 $mouse + ;; + mwave) + makedev mwave c 10 219 $mouse + ;; + systrace) + makedev systrace c 10 226 $private + ;; + uinput) + makedev input/uinput c 10 223 $mouse ;; js) major=`Major Joystick 13` || continue @@ -1089,16 +1134,6 @@ do makedev djs$unit c $major `math $unit + 128` $readable done ;; - fd[0-7]-bare) - sarg="${arg%-bare}" - major=`Major fd 2` || continue - base=`suffix $sarg fd` - if [ $base -ge 4 ] - then - base=`math $base + 124` - fi - makedev ${sarg} b $major $base $floppy - ;; fd[0-7]) major=`Major fd 2` || continue base=`suffix $arg fd` @@ -1217,6 +1252,58 @@ do makedev hd$unit$part b $major $(( $base + $part )) $disk done ;; + hd[m-n]) + major=`Major ide6 88` || continue + unit=`suffix $arg hd` + base=`index mn $unit` + base=`math $base \* 64` + makedev hd$unit b $major $base $disk + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + do + makedev hd$unit$part b $major $(( $base + $part )) $disk + done + ;; + hd[o-p]) + major=`Major ide7 89` || continue + unit=`suffix $arg hd` + base=`index op $unit` + base=`math $base \* 64` + makedev hd$unit b $major $base $disk + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + do + makedev hd$unit$part b $major $(( $base + $part )) $disk + done + ;; + hd[q-r]) + major=`Major ide8 90` || continue + unit=`suffix $arg hd` + base=`index qr $unit` + base=`math $base \* 64` + makedev hd$unit b $major $base $disk + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + do + makedev hd$unit$part b $major $(( $base + $part )) $disk + done + ;; + hd[s-t]) + major=`Major ide9 91` || continue + unit=`suffix $arg hd` + base=`index st $unit` + base=`math $base \* 64` + makedev hd$unit b $major $base $disk + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + do + makedev hd$unit$part b $major $(( $base + $part )) $disk + done + ;; + ub|uba) + major=180 + makedev uba b $major 0 $disk + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + do + makedev uba$part b $major $part $disk + done + ;; ht0) major=`Major ht0 37` || continue # Only one IDE tape drive is currently supported; ht0. @@ -1282,6 +1369,58 @@ do minor=$(( $base + $part )) makedev sd$unit$part b $major $minor $disk done + ;; + i2o.hd[a-z]) + [ -d i2o ] || { + mkdir i2o + chown root:root i2o + chmod 755 i2o + [ -e i2o/ctl ] || makedev i2o/ctl c 10 166 $disk + } + unit=`suffix $arg i2o.hd` + base=`index abcdefghijklmnopqrstuvwxyz $unit` + base=$(( $base * 16 )) + if [ $base -lt 256 ]; then + major=80 + else + major=81 + base=$(( $base - 256 )) + fi + makedev i2o/hd$unit b $major $base $disk + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + do + minor=$(( $base + $part )) + makedev i2o/hd$unit$part b $major $minor $disk + done + ;; + i2o.hd[a-d][a-z]) + [ -d i2o ] || { + mkdir i2o + chown root:root i2o + chmod 755 i2o + [ -e i2o/ctl ] || makedev i2o/ctl c 10 166 $disk + } + unit=`suffix $arg i2o.hd` + unitmaj=`first $unit` + unitmin=`second $unit` + basemaj=`index Xabcd $unitmaj` + basemin=`index abcdefghijklmnopqrstuvwxyz $unitmin` + basemaj=`math $basemaj \* 416` + basemin=`math $basemin \* 16` + base=`math $basemaj + $basemin` + basemaj=`math $base / 256` + base=`math $base % 256` + major=`math basemaj \+ 80` + if [ $major -gt 87 ]; then + echo "$0: don't know how to make device \"$arg\"" >&2 + exit 0 + fi + makedev i2o/hd$unit b $major $base $disk + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + do + minor=$(( $base + $part )) + makedev i2o/hd$unit$part b $major $minor $disk + done ;; dasd[a-z]) major=`Major dasd 94` || continue @@ -1295,9 +1434,7 @@ do base=$(( $base - 256 )) fi makedev dasd$unit b $major $base $disk - # Not yet implemented. (Feb. 8, 2001) - # for part in 1 2 3 - for part in 1 + for part in 1 2 3 do minor=$(( $base + $part )) makedev dasd$unit$part b $major $minor $disk @@ -1320,6 +1457,7 @@ do do $0 $opts dac960.$ctr done + makedev dac960_gam c 10 252 $disk ;; dac960.[0-7]) [ -d rd ] || { @@ -1342,6 +1480,14 @@ do done done ;; + dpti) + major=151 + for ld in 1 2 3 4 5 6 7 + do + minor=`math $ld -1` + makedev dpti${ld} c $major $minor $disk + done + ;; ataraid) for ctr in 0 1 2 # 3 4 5 6 7 do @@ -1354,16 +1500,16 @@ do chown root:root ataraid chmod 755 ataraid } - unit=`suffix $arg ataraid.` - major=114 - minor=`math $unit \* 16` - makedev ataraid/d${unit} b $major $minor $disk - for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - do - minor=`math $minor + 1` - makedev ataraid/d${unit}p$part b $major $minor $disk - done - ;; + unit=`suffix $arg ataraid.` + major=114 + minor=`math $unit \* 16` + makedev ataraid/d${unit} b $major $minor $disk + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + do + minor=`math $minor + 1` + makedev ataraid/d${unit}p$part b $major $minor $disk + done + ;; ida) for ctr in 0 1 2 # 3 4 5 6 7 do @@ -1437,6 +1583,10 @@ do makedev loop$part b 7 $part $disk done ;; + loop[0-9]|loop[1-9][0-9]|loop1[0-9][0-9]|loop2[0-4][0-9]|loop25[0-5]) + minor=`suffix $arg loop` + makedev loop$minor b 7 $minor $disk + ;; md) major=`Major md 9` || continue for part in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @@ -1511,7 +1661,7 @@ do major=`Major sr 11` || continue unit=`suffix $arg scd` makedev scd$unit b $major $unit $cdrom - ln -f scd$unit sr$unit + symlink sr$unit scd$unit ;; ttyI[0-9]|ttyI[1-5][0-9]|ttyI[6][0-3]) major=43 @@ -1612,7 +1762,7 @@ do makedev ${arg}0 b $major 0 $cdrom ;; pcd) - for unit in 0 1 2 3 + for unit in 0 1 2 3 do makedev pcd$unit b 46 $unit $cdrom done @@ -1629,8 +1779,9 @@ do cfs|coda) makedev cfs0 c 67 0 $private ;; - xfs|arla) + xfs|nnpfs|arla) makedev xfs0 c 103 0 $private + makedev nnpfs0 c 103 0 $private ;; logiscan) major=`Major logiscan` || continue @@ -1722,7 +1873,7 @@ do # devices might be good, but 8 should suffice for now major=`Major i2c 89` || continue minor=0 - until [ $minor -gt 7 ] + until [ $minor -gt 7 ] do makedev i2c-$minor c $major $minor $private minor=`math $minor + 1` @@ -1825,6 +1976,47 @@ do makedev comedi$minor c $major $minor $public done ;; + tilp) + for i in `seq 0 7` + do + makedev tipar$i c 115 $i $printer + makedev tiser$i c 115 `math 8 + $i` $dialout + done + for i in `seq 0 31` + do + makedev tiusb$i c 115 `math 16 + $i` $dialout + done + ;; + dvb) + # check if kernel-version is >= 2.6.8, if yes, create dvb-devices with + # major-number 212, in the other case 250 + + kern_rev1=`uname -r | sed -e 's@^\([^.]*\)\..*@\1@'` + kern_rev2=`uname -r | sed -e 's@^[^.]*\.\([^.]*\)\..*@\1@'` + kern_rev3=`uname -r | sed -e 's@^[^.]*\.[^.]*\.\([^.][0-9]*\).*@\1@'` + + dvb_major=250 + + if [ $kern_rev1 -gt 2 ] || ([ $kern_rev1 -eq 2 ] && [ $kern_rev2 -gt 6 ]) \ + || ([ $kern_rev1 -eq 2 ] && [ $kern_rev2 -eq 6 ] && [ $kern_rev3 -ge 8 ]) + then + dvb_major=212 + fi + + mkdir -p dvb + for i in 0 1 2 3 + do + mkdir -p dvb/adapter$i + makedev dvb/adapter$i/video0 c $dvb_major `math 64 \* $i + 0` $video + makedev dvb/adapter$i/audio0 c $dvb_major `math 64 \* $i + 1` $video + makedev dvb/adapter$i/frontend0 c $dvb_major `math 64 \* $i + 3` $video + makedev dvb/adapter$i/demux0 c $dvb_major `math 64 \* $i + 4` $video + makedev dvb/adapter$i/dvr0 c $dvb_major `math 64 \* $i + 5` $video + makedev dvb/adapter$i/ca0 c $dvb_major `math 64 \* $i + 6` $video + makedev dvb/adapter$i/net0 c $dvb_major `math 64 \* $i + 7` $video + makedev dvb/adapter$i/osd0 c $dvb_major `math 64 \* $i + 8` $video + done + ;; usb) mkdir -p usb major=180 @@ -1834,30 +2026,67 @@ do makedev usb/mouse$i c $major `math $i + 16` $mouse makedev usb/ez$i c $major `math $i + 32` $system makedev usb/scanner$i c $major `math $i + 48` $scanner + makedev usb/hiddev$i c $major `math $i + 96` $system makedev ttyACM$i c 166 $i $dialout makedev ttyUSB$i c 188 $i $dialout done makedev usb/rio500 c $major 64 $audio + makedev usb/usblcd c $major 65 $audio + makedev usb/cpad0 c $major 66 $audio + ;; + bluetooth) + major=216 + for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \ + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + do + makedev rfcomm$i c $major $i $dialout + done + makedev vhci c 10 250 $dialout + for i in 0 1 2 3; do + makedev ttyUB$i c 216 $i $dialout + makedev ccub$i c 217 $i $dialout + done ;; paride) - major=45 - for unit in a b c d + major=45 + for unit in a b c d do - base=`index abcd $unit` - base=`math $base \* 16` - makedev pd$unit b $major $base $disk - for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - do - makedev pd$unit$part b $major $(( $base + $part )) $disk - done + base=`index abcd $unit` + base=`math $base \* 16` + makedev pd$unit b $major $base $disk + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + do + makedev pd$unit$part b $major $(( $base + $part )) $disk + done done for i in 0 1 2 3 do - makedev pcd$i b 46 $i $cdrom - makedev pf$i b 47 $i $floppy + makedev pcd$i b 46 $i $cdrom + makedev pf$i b 47 $i $floppy done - ;; + ;; update) + devices= + if [ ! -f $procfs/devices ] + then + echo "$0: warning: can't read $procfs/devices" >&2 + else + exec 3<$procfs/devices + while read major device extra <&3 + do + device=`echo $device | sed 's#/.*##'` + case "$major" in + Character|Block|'') + ;; + *) + eval "major_$device=$major" + devices="$devices $device" + ;; + esac + done + exec 3<&- + fi + if [ ! "$devices" ] then echo "$0: don't appear to have any devices" >&2 @@ -1876,7 +2105,7 @@ do exec 3<DEVICES while read device major <&3 do - eval now=\$major_${device/-/_} + eval now=\$major_$device if [ "$now" = "" ] then delete="$delete `cvt $device`" @@ -1897,7 +2126,7 @@ do do if [ "`cvt $device`" ] then - eval echo $device \$major_${device/-/_} + eval echo $device \$major_$device fi done > DEVICES ;; diff --git a/sbin/functions.sh b/sbin/functions.sh index 5c5d870..3838e69 100755 --- a/sbin/functions.sh +++ b/sbin/functions.sh @@ -36,6 +36,7 @@ RC_ENDCOL="yes" # RC_TTY_NUMBER=${RC_TTY_NUMBER:-0} RC_PARALLEL_STARTUP=${RC_PARALLEL_STARTUP:-no} +RC_NET_STRICT_CHECKING=${RC_NET_STRICT_CHECKING:-no} # # Default values for e-message indentation and dots @@ -3,6 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 trap ":" INT QUIT TSTP + source /sbin/functions.sh umask 022 @@ -150,6 +151,22 @@ dep_stop() { [[ ! -L ${svcdir}/softscripts.new/${myservice} ]] || \ return 0 + # If this is a 'net' service, we do not want to stop it if it was + # not in the previous runlevel, and we are not shutting down, + # rebooting or going to single runlevel. This is because the user + # (or hotplut) might have started it (net.ppp?) ... + if net_service "${myservice}" && \ + [[ ${SOFTLEVEL} != "reboot" && \ + ${SOFTLEVEL} != "shutdown" && \ + ${SOFTLEVEL} != "single" ]] ; then + if [[ -z ${OLDSOFTLEVEL} ]] || \ + ! in_runlevel "${myservice}" "${OLDSOFTLEVEL}" ; then + # This service is not in the previous runlevel, so + # do not stop it ... + return 0 + fi + fi + # Should not work for 'use' if [[ -z $(needsme "${myservice}") ]] ; then # Nothing depends on me diff --git a/sbin/rc-services.sh b/sbin/rc-services.sh index 4a177cd..0badfd5 100755 --- a/sbin/rc-services.sh +++ b/sbin/rc-services.sh @@ -601,6 +601,50 @@ service_failed() { [[ -n $1 && -L ${svcdir}/failed/$1 ]] } +# bool net_service(service) +# +# Returns true if 'service' is a service controlling a network interface +# +net_service() { + [[ -n $1 && ${1%%.*} == "net" && ${1##*.} != "$1" ]] +} + +# bool is_net_up() +# +# Return true if service 'net' is considered up, else false. +# +# Notes for RC_NET_STRICT_CHECKING values: +# none net is up without checking anything - usefull for vservers +# lo Interface 'lo' is counted and if only it is up, net is up. +# no Interface 'lo' is not counted, and net is down even with it up, +# so there have to be at least one other interface up. +# yes All interfaces must be up. +is_net_up() { + local netcount=0 + + case "${RC_NET_STRICT_CHECKING}" in + none) + return 0 + ;; + lo) + netcount="$(ls -1 "${svcdir}"/started/net.* 2> /dev/null | \ + egrep -c "\/net\..*$")" + ;; + *) + netcount="$(ls -1 "${svcdir}"/started/net.* 2> /dev/null | \ + grep -v 'net\.lo' | egrep -c "\/net\..*$")" + ;; + esac + + # Only worry about net.* services if this is the last one running, + # or if RC_NET_STRICT_CHECKING is set ... + if [[ "${netcount}" -lt 1 || ${RC_NET_STRICT_CHECKING} == "yes" ]] ; then + return 1 + fi + + return 0 +} + # bool dependon(service1, service2) # # Does service1 depend (NEED or USE) on service2 ? @@ -625,7 +669,8 @@ valid_i() { for x in $( i$1 "$2" ) ; do [[ -e /etc/runlevels/${BOOTLEVEL}/${x} || \ - -e "/etc/runlevels/${mylevel}/${x}" ]] \ + -e "/etc/runlevels/${mylevel}/${x}" || \ + ${x} == "net" ]] \ && echo "${x}" done @@ -660,7 +705,18 @@ trace_dependencies() { if [[ $1 == -* ]] ; then deptype=${1/-} - services=( "${myservice}" ) + if net_service "${myservice}" ; then + services=( "net" "${myservice}" ) + else + services=( "${myservice}" ) + fi + fi + + # If its a net service, just replace it with 'net' + if [[ -z ${deptype} ]] ; then + for (( i=0; i<${#services[@]} ; i++ )) ; do + net_service "${services[i]}" && services[i]="net" + done fi sort_unique() { @@ -684,6 +740,11 @@ trace_dependencies() { ndeps=( "${ndeps[@]}" $( valid_iafter "${services[i]}" ) ) fi + #If its a net service, just replace it with 'net' + for (( j=0; j<${#ndeps[*]}; j++ )) ; do + net_service "${ndeps[j]}" && ndeps[j]="net" + done + deps=( "${deps[@]}" "${ndeps[@]}" ) fi done @@ -715,6 +776,13 @@ trace_dependencies() { deps="${deps} $( valid_iafter ${service} )" fi + if [[ -z ${deptype} ]] ; then + # If its a net service, just replace it with 'net' + for (( j=0; j<${#deps[@]}; j++ )) ; do + net_service "${deps[j]}" && deps[j]="net" + done + fi + for x in ${deps} ; do after_visit "${x}" done @@ -731,6 +799,43 @@ trace_dependencies() { # If deptype is set, we do not want the name of this service x=" ${services[@]} " services=( ${x// ${myservice} / } ) + + # If its a net service, do not include "net" + if net_service "${myservice}" ; then + x=" ${services[@]} " + sorted=( ${services// net / } ) + fi + else + local netserv y + + # XXX: I dont think RC_NET_STRICT_CHECKING should be considered + # here, but you never know ... + netserv=$( cd "${svcdir}"/started; ls net.* 2>/dev/null ) + + get_netservices() { + local runlevel=$1 + + if [[ -d /etc/runlevels/${runlevel} ]] ; then + cd "/etc/runlevels/${runlevel}" + ls net.* 2>/dev/null + fi + } + + # If no net services are running or we only have net.lo up, then + # assume we are in boot runlevel or starting a new runlevel + if [[ -z ${netserv} || ${netserv} == "net.lo" ]] ; then + local mylevel=${BOOTLEVEL} + local startnetserv=$( get_netservices "${mylevel}" ) + + [[ -f ${svcdir}/softlevel ]] && mylevel=$( < "${svcdir}/softlevel" ) + [[ ${BOOTLEVEL} != "${mylevel}" ]] && \ + startnetserv="${startnetserv} $( get_netservices "${mylevel}" )" + [[ -n ${startnetserv} ]] && netserv=${startnetserv} + fi + + # Replace 'net' with the actual net services + x=" ${services[@]} " + services=( ${x// net / ${netserv} } ) fi echo "${services[@]}" @@ -743,13 +848,19 @@ trace_dependencies() { # query_before() { local x list + local netservice="no" [[ -z $1 || -z $2 ]] && return 1 list=$( trace_dependencies "$1" ) + net_service "$2" && netservice="yes" + for x in ${list} ; do [[ ${x} == "$2" ]] && return 0 + + # Also match "net" if this is a network service ... + [[ ${netservice} == "yes" && ${x} == "net" ]] && return 0 done return 1 diff --git a/sbin/rc-update b/sbin/rc-update index 90c0b7a..a4150f8 100755 --- a/sbin/rc-update +++ b/sbin/rc-update @@ -11,16 +11,16 @@ usage: rc-update -a|add script runlevel2 [runlevel2 ...] rc-update -s|show [runlevel1 ...] examples: - # rc-update add sysklogd default - Adds the sysklogd script (in /etc/init.d) to the "default" runlevel. + # rc-update add net.eth0 default + Adds the net.eth0 script (in /etc/init.d) to the "default" runlevel. # rc-update del sysklogd Deletes the sysklogd script from all runlevels. The original script is not deleted, just any symlinks to the script in /etc/runlevels/*. - # rc-update del sysklogd default wumpus - Delete the sysklogd script from the default and wumpus runlevels. - All other runlevels are unaffected. Again, the sysklogd script + # rc-update del net.eth2 default wumpus + Delete the net.eth2 script from the default and wumpus runlevels. + All other runlevels are unaffected. Again, the net.eth2 script residing in /etc/init.d is not deleted, just any symlinks in /etc/runlevels/default and /etc/runlevels/wumpus. diff --git a/sbin/runscript.sh b/sbin/runscript.sh index 79820f3..aec6799 100755 --- a/sbin/runscript.sh +++ b/sbin/runscript.sh @@ -30,14 +30,26 @@ myservice=${myservice##*/} export SVCNAME=${myservice} mylevel=$(<"${svcdir}/softlevel") +# Set $IFACE to the name of the network interface if it is a 'net.*' script +if [[ ${myservice%%.*} == "net" && ${myservice##*.} != "${myservice}" ]] ; then + IFACE=${myservice##*.} + NETSERVICE="yes" +else + IFACE= + NETSERVICE= +fi + # Source configuration files. # (1) Source /etc/conf.d/${myservice} to get initscript-specific # configuration (if it exists). -# (2) Source /etc/rc.conf to pick up potentially overriding +# (2) Source /etc/conf.d/net if it is a net.* service +# (3) Source /etc/rc.conf to pick up potentially overriding # configuration, if the system administrator chose to put it # there (if it exists). [[ -e $(add_suffix /etc/conf.d/${myservice}) ]] && source "$(add_suffix /etc/conf.d/${myservice})" +[[ -e $(add_suffix /etc/conf.d/net) ]] && \ +[[ ${NETSERVICE} == "yes" ]] && source "$(add_suffix /etc/conf.d/net)" [[ -e $(add_suffix /etc/rc.conf) ]] && source "$(add_suffix /etc/rc.conf)" usage() { @@ -102,7 +114,21 @@ svc_stop() { fi if [[ ${svcpause} != "yes" ]] ; then - mydeps=${myservice} + if [[ ${NETSERVICE} == "yes" ]] ; then + # A net.* service + if in_runlevel "${myservice}" "${BOOTLEVEL}" || \ + in_runlevel "${myservice}" "${mylevel}" ; then + # Only worry about net.* services if this is the last one running, + # or if RC_NET_STRICT_CHECKING is set ... + if ! is_net_up ; then + mydeps="net" + fi + fi + + mydeps="${mydeps} ${myservice}" + else + mydeps=${myservice} + fi fi # Save the IN_BACKGROUND var as we need to clear it for stopping depends @@ -266,18 +292,53 @@ svc_start() { # Start dependencies, if any for x in ${startupservices} ; do - if service_stopped "${x}" ; then - start_service "${x}" + if [[ ${x} == "net" ]] && [[ ${NETSERVICE} != "yes" ]] && ! is_net_up ; then + local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \ + $(dolisting "/etc/runlevels/${mylevel}/net.*")" + + for y in ${netservices} ; do + mynetservice=${y##*/} + if service_stopped "${mynetservice}" ; then + start_service "${mynetservice}" + fi + done + elif [[ ${x} != "net" ]] ; then + if service_stopped "${x}" ; then + start_service "${x}" + fi fi done # wait for dependencies to finish for x in ${startupservices} ; do - wait_service "${x}" - if ! service_started "${x}" ; then - # A 'need' dependacy is critical for startup - if ineed -t "${myservice}" "${x}" >/dev/null ; then - startfail="yes" + if [ "${x}" = "net" -a "${NETSERVICE}" != "yes" ] ; then + local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \ + $(dolisting "/etc/runlevels/${mylevel}/net.*")" + + for y in ${netservices} ; do + mynetservice="${y##*/}" + + wait_service "${mynetservice}" + + if ! service_started "${mynetservice}" ; then + # A 'need' dependency is critical for startup + if ineed -t "${myservice}" "${x}" >/dev/null ; then + # Only worry about a net.* service if we do not have one + # up and running already, or if RC_NET_STRICT_CHECKING + # is set .... + if ! is_net_up ; then + startfail="yes" + fi + fi + fi + done + elif [ "${x}" != "net" ] ; then + wait_service "${x}" + if ! service_started "${x}" ; then + # A 'need' dependacy is critical for startup + if ineed -t "${myservice}" "${x}" >/dev/null ; then + startfail="yes" + fi fi fi done diff --git a/src/awk/cachedepends.awk b/src/awk/cachedepends.awk index 1e508a1..017e231 100644 --- a/src/awk/cachedepends.awk +++ b/src/awk/cachedepends.awk @@ -44,6 +44,10 @@ function print_header2(mtime) { print "" >> TMPCACHE print " [ -e \"/etc/conf.d/${myservice}\" ] && source \"/etc/conf.d/${myservice}\"" >> TMPCACHE print "" >> TMPCACHE + print " [ -e /etc/conf.d/net ] && \\" >> TMPCACHE + print " [ \"${myservice%%.*}\" = \"net\" ] && \\" >> TMPCACHE + print " [ \"${myservice##*.}\" != \"${myservice}\" ] && source /etc/conf.d/net" >> TMPCACHE + print "" >> TMPCACHE print " [ -e /etc/rc.conf ] && source /etc/rc.conf" >> TMPCACHE print "" >> TMPCACHE print " depend() {" >> TMPCACHE diff --git a/src/awk/gendepends.awk b/src/awk/gendepends.awk index 5a7f9de..c4073b4 100644 --- a/src/awk/gendepends.awk +++ b/src/awk/gendepends.awk @@ -259,7 +259,7 @@ function resolve_depend(type, service, deplist, x, deparray) # should handle invalid database entries currently. if (!check_service(deparray[x])) { - if (((type == NEED) || (type == NEEDME))) { + if (((type == NEED) || (type == NEEDME)) && (deparray[x] != "net")) { ewarn(" Can't find service '" deparray[x] "' needed by '" service "'; continuing...") @@ -268,7 +268,8 @@ function resolve_depend(type, service, deplist, x, deparray) continue } - continue + else if (deparray[x] != "net") + continue } # Ugly bug ... if a service depends on itself, it creates @@ -468,6 +469,12 @@ BEGIN { } END { + # Add the 'net' service if it do not exist ... + if (!check_service("net")) { + RC_NUMBER++ + DEPTREE[RC_NUMBER,NAME] = "net" + } + # Calculate all the provides ... for (x = 1;x <= RC_NUMBER;x++) { if ((x,PROVIDE) in DEPTREE) |