See also: [MWRPFrottleDevDiscussion] (when it gets rewritten) This is a quick diary of DanFlett's experiences installing (http://frottle.sourceforge.net/ Frottle) under Debian. Feel free to edit the info here into a more generic and informational HOWTO. ! Initial Efforts First off, I read the Frottle page above and followed the instructions as best I could. The first thing it says to do is download the (ftp://ftp.netfilter.org/pub/iptables/ source) for the version of IPTABLES you have installed. I had 1.2.6a installed - a bit old, so I ended up being lazy and installed the latest IPTABLES Debian package: apt-get install iptables I run Debian Unstable, so as of 2005/02/14 I ended up with IPTABLES v1.2.11. The Frottle docs say once you've downloaded and untar'd the IPTABLES source you do a make make install-devel I didn't do this first. I found a Debian package called iptables-dev so I installed it: apt-get install iptables-dev According to the package blurb, IPTABLES-DEV is "Header files, static libs and documentation for libipq (iptables user-space packet queuing library) and libiptc." I went back into where I'd untar'd Frottle and did ./configure then make and got errors - it couldn't find the file libipq.h. I would have thought installing iptables-dev would put it there in the right spot but I couldn't find it on my system. As a precaution I also followed the advice in the Frottle INSTALL file: There is a 'feature' in iptables which may cause make to fail. If you get errors like: /usr/include/net/if.h:45: parse error before `0x1' /usr/include/net/if.h:111: redefinition of `struct ifmap' etc Then you need to edit /usr/include/linux/netfilter_ipv4/ip_queue.h and change "#include " to "#include ". I was also thinking about changing the "prefix" definition in both the Frottle and IPTABLES makefiles to "/usr" instead of "/usr/local" because I noticed that Debian tends to install stuff, including the IPTABLES package under "/usr" and not "/usr/local". In the end I didn't. I just followed followed Frottle's instructions - I downloaded and untar'd IPTABLES v1.2.11, ran "make" then "make intstall-devel". I then went to the Frottle source directory and ran "./configure" then "make" (it worked this time) then "make install". ---- Under Debian... find /usr -name libipq.h -print returns /usr/include/libipq/libipq.h we can cheat by fudging it... ln -s /usr/include/libipq/libipq.h /usr/include/libipq.h and it will be picked up properly without any tarball efforts, although it still needs the ''ip_queue.h'' mods though --[GlennMcKechnie] You found this after the IPTABLES-DEV package was installed? I assume so since I installed the IPTABLES-DEV Debian package but not the IPTables source with "make install-devel". It would be nice if we could use the IPTABLES-DEV package and fudge it to make it work... --DanFlett Yes, the development package was still needed. It contains the required header file.--[GlennMcKechnie] Ah! Someone else has a very elegant solution to all the above issues - check this link: (http://mother.lugmen.org.ar/pipermail/lug-wireless/2003-August/004593.html http://mother.lugmen.org.ar/pipermail/lug-wireless/2003-August/004593.html) Summary: After trying to compile frottle on my debian 3.0 (own cc'ed 2.4.20) I came up to cc errors you describe in INSTALL, ie net/if.h vs linux/if.h "conflicts". Instead of editing headers I've successfully built with: # apt-get install iptables-dev ###headers & libs $ CPPFLAGS="-I/usr/include/libipq -D_NET_IF_H" ./configure $ make Can someone explain what Juan did there? What is being done with libipq? Is something being compiled statically into Frottle? Now suppose I want to create a Frottle Debian package - can I use this advice? --DanFlett ---- Juan has provided a solution that passes the path (-I denotes include) of the required header to the compiler itself. It doesn't require messing with links or the like and is the purpose of CPPFLAGS/CFLAGS, it's therefore a preferred solution. Nothing is being compiled statically, the process is the same as before except the path to the libipq.h file is being passed another way. If you were creating a new source package then this argument needs to be incorporated into the configure script, it also needs to be crafted to catch Debian, Fedora and the Unameit distributions differences. This is perhaps where someone better versed in the subject could step in... {/regexpicons/emoticons/emoticon-face3.png ;)} -- [GlennMcKechnie] ---- This all seemed to work fine. Then I decided I wanted to make it all Debianesque in the /usr directory so I uninstalled Frottle and IPTABLES-devel and did it all again, this time I did edit the "prefix" in the Makefiles of both Frottle and IPTABLES to point at "/usr" instead of "/usr/local". ---- No need for Makefile edits... ./configure --help will show the following to work ./configure --prefix=/usr -[GlennMcKechnie] I'd add that leaving oddball packages like this in ''/usr/local'' is fine, it's what ''/usr/local'' is for. It an advantage when it comes to working out what is actually ''different'' between two systems, all non-standard packages can be found in ''/usr/local'' so a quick scan of the directories shows what extra files/packages have been installed. ---- This didn't work. I had to edit configure.in to point at /usr instead of /usr/local, ans when I did that and ran "make install" it complained about autoconf-1.6 being missing. Frottle got installed to /usr/bin where I wanted it, but when I went to run it the shell was still looking in /usr/local/bin. At this point I gave up trying to Debianize that particular aspect of Frottle, and went back to /usr/local. ---- I've come across this myself, it's remembering the last location of the file. Logging out and back in may clear it, otherwise just specify the path until it clears. -- [GlennMcKechnie] ---- ---- ! Installing Modules Frottle creates /etc/frottle.conf.sample - which needs to be renamed to /etc/frottle.conf and edited to specify what mode you want to run it in. Now we need to decide the most Debianesque way of installing the required modules - iptable_filter and ip_queue - I say just chuck those modules in /etc/modules, but I'm open to suggestions. I run Shorewall and the needed modules seem to get loaded when Shorewall runs (I think), but putting them in /etc/modules covers systems that don't run Shorewall. What's the most distro-neutral way for a package to make sure required modules are loaded? --DanFlett 2005/02/16 ---- ''/etc/modules'' is debian (and friends) only. Putting them in there (or the equivalent in other distros) means they load at boot up, whether they're needed or not. Insmod works for them all I believe, certainly >2.4. , so perhaps just call them from the start up script. 2> /dev/null the output for cases where the modules are already loaded. Regardless of the method though good documentation in the form of INSTALL notes will be the key, especially if a kernel build is required. {/regexpicons/emoticons/emoticon-face3.png ;)} --[GlennMcKechnie] ---- After I'm finished playing with Frottle, I might just submit a new INSTALL file as a patch to their CVS. {/regexpicons/emoticons/emoticon-face3.png ;)} --DanFlett 2005/02/16 ---- ---- ! IPTables Rules Frottle also requires some IPTABLES rules to operate properly. In Client mode: iptables -A INPUT -p UDP --sport 999 -j ACCEPT # Allow control packets in iptables -A OUTPUT -p UDP --dport 999 -j ACCEPT # Allow control packets out iptables -A OUTPUT -p ALL -o eth1 -j QUEUE # where eth1 is the wireless interface iptables -A FORWARD -p ALL -o eth1 -j QUEUE # where eth1 is the wireless interface In Master mode: iptables -A INPUT -p UDP --dport 999 -j ACCEPT # Allow control packets in iptables -A OUTPUT -p UDP --sport 999 -j ACCEPT # Allow control packets out iptables -A OUTPUT -p ALL -o eth1 -j QUEUE # where eth1 is the wireless interface iptables -A FORWARD -p ALL -o eth1 -j QUEUE # where eth1 is the wireless interface I think putting these in a Frottle init script would be the best place for them. I'm no IPTABLES guru, so can anyone suggest a complimentary set of rules to cancel these when Frottle is shut down? ---- I think I've worked it out: iptables -D INPUT -p UDP --dport 999 -j ACCEPT iptables -D OUTPUT -p UDP --sport 999 -j ACCEPT iptables -D OUTPUT -p ALL -o eth1 -j QUEUE iptables -D FORWARD -p ALL -o eth1 -j QUEUE -D to delete the rules added. Is this correct? --DanFlett 2005/02/16 ---- Yes --[GlennMcKechnie] ---- ---- ! Initialisation Next comes the init.d file - I'm going to use /etc/init.d/skeleton as a base. The problem with putting the iptables rules in an init file is the init file needs to know if Frottle is being run in Master or Client mode to know which set of iptables rules to execute. So maybe we need separate init files for frottle master and frottle client. /etc/init.d/skeleton wants one to use 'start-stop-daemon' so I'll see if I can use that. It would be useful if we can run two instances of frottle - one in Master mode and one in Client mode... ---- You could pass 'master' or 'client' as an argument to the startup script and thereby get it to behave differently depending on the ''mode''. Ideally the pid should be generated by frottle itself as it would then be portable to other distros, start-stop-daemon is a Debianism I think. --[GlennMcKechnie] ---- I thought of doing that - and also of passing other arguments such as the port and interface to the startup script - the problem is - how do you get Debian to pass those arguments at boot-time? It's almost like we need a script within a script - the init.d script shoud be pretty simple and simply start or stop Frottle. We then have a wrapper script for it that takes care of interfaces, ports, master/client mode, etc. What would be ideal is if Frottle itself could call it's own iptables scripts (depending on mode) and pass interface and port arguments to it. I've been emailing the Frottle developers and am trying to get some discussion happening. I'm still waiting for them to get back to me. Ultimately, if there's any willing and able C programmers available, we could just get the source and modify it ourselves (and add PID generation while we're at it). Until then, we can just muddle along with wrapper scripts. --DanFlett 2005/02/16 So, you want a patch that does what? * Dump the pid to a file specified as part of the configuration * Will call a script specified as part of the configuration (the script would load IPTABLE rules). * Will call a script on shutdown (to unload IPTABLE rules) * Command line arguments -mode -interface -port * ?? Additional parameters in the config file could be: # pid file location #pidFile /var/run/frottle # Client launch script (run during initialization) #clientLaunch /usr/local/frottle_pre_client.sh # Client shutdown script (run during exit) #clientExit /usr/local/frottle_post_client.sh # Master launch script #masterLaunch /usr/local/frottle_pre_master.sh # Master shutdown script #masterExit /usr/local/frottle_post_master.sh Adding arguments is easy, calling scripts is easy. Deciding what you really want is the hard part. --[dna] ---- Put the rules, port and other specific variables in two config files - ''/etc/frottle-client.conf'' and ''/etc/frottle-master.conf''. When the script runs it can check if a config file exists * if it doesn't it can be assumed that mode isn't required, so fall through to the next operation. * if it does exist, source the arguments ('''. /etc/frottle-client.conf''')eg:- PORT=xxx, RULE="iptables -A INPUT -p UDP --sport $PORT -j ACCEPT" so that they are directly available to the script -- or that ''loop'' of the script. There's bound to be a suitable "PID with case" example somewhere we can borrow, however for the moment just run with the debian case to see if it works for us. While it's not critical to do it, best practice suggests we should consider cases beyond our immediate interests. Even if we don't act in '''all''' cases we can minimize the changes that may be needed for someone else to add their bit. --[GlennMcKechnie] ---- I've thought of a different approach - how about configuring all aspects of Frottle with a wrapper script - and the wrapper script creates temporary config files for each instance of frottle running - and deletes them when frottle is shut down? That way we can control the modules, IPtables script, the interfaces and ports it is running on, and which mode for which interface - all in the one place. To shut frottle down the init script just does a 'killall -TERM frottle' just like it says in the docs - and we don't have to worry about PIDs. At the start of the wrapper script you edit the variables to configure how it runs - or the wrapper script could possibly have it's own config file. {/regexpicons/emoticons/emoticon-face1.png :)} I'll write something and post it here... --DanFlett 2005/02/16 ---- Creating temporary config files seems messy although having one central config during testing would be an advantage. Do you need to control them seperately? killall will literally '''kill all''' so both instances of 'frottle' will die, you could hard link frottle as (say) frottle-master if it mattered. Until the script is posted... --[GlennMcKechnie] ---- ---- ! Initialisation Files '''/etc/init.d/frottle-client''' This script calls Frottle in client mode - for one interface, and uses Debian's 'start-stop-daemon' to create a PID file. It can then kill the specific instance of Frottle that it called using the PID, without killing other instances. that for example, may be running on other interfaces in a different mode. It uses the config file /etc/frottle-client.conf - perhaps /etc/frottle/frottle-client.conf might be better? '''To Do:'' * Modify it so it can call (and shut down) separate client instances for different interfaces. ** Find out if multiple interfaces can all share UDP port 999 for Frottle control messages ++++ #! /bin/sh # # Frottle Client init script by Dan Flett 2005 # #Put your Frottle Client interface here INTERFACE="wlan0" #Change this to the port you are running Frottle on PORT=999 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin NAME=frottle CONF=/etc/frottle-client.conf BINDIR=/usr/local/bin BIN=$BINDIR/$NAME ARGS="-c $CONF -d" PIDFILE=/var/run/frottle-client.pid DESC="Frottle Client" test -x $BIN || exit 0 set -e case "$1" in start) echo -n "Starting $DESC " iptables -A INPUT -p UDP --sport $PORT -j ACCEPT # Allow control packets in iptables -A OUTPUT -p UDP --dport $PORT -j ACCEPT # Allow control packets out iptables -A OUTPUT -p ALL -o $INTERFACE -j QUEUE # All other traffic out via QUEUE target iptables -A FORWARD -p ALL -o $INTERFACE -j QUEUE # All other forwarded traffic via QUEUE target start-stop-daemon --start --pidfile $PIDFILE --make-pidfile --exec $BIN -- $ARGS echo "." ;; stop) echo -n "Stopping $DESC " PID=`cat $PIDFILE` PID1=`expr $PID + 1` PID2=`expr $PID + 2` PID3=`expr $PID + 3` kill $PID1 $PID2 $PID3 rm $PIDFILE # #Please check the below rules - I'm not sure this is how they work -- Dan # iptables -D INPUT -p UDP --sport $PORT -j ACCEPT #Delete iptables rules iptables -D OUTPUT -p UDP --dport $PORT -j ACCEPT iptables -D OUTPUT -p ALL -o $INTERFACE -j QUEUE iptables -D FORWARD -p ALL -o $INTERFACE -j QUEUE echo "." ;; restart|force-reload) echo -n "Restarting $DESC " PID=`cat $PIDFILE` PID1=`expr $PID + 1` PID2=`expr $PID + 2` PID3=`expr $PID + 3` kill $PID1 $PID2 $PID3 rm $PIDFILE # #Please check the below rules - I'm not sure this is how they work -- Dan # iptables -D INPUT -p UDP --sport $PORT -j ACCEPT #Delete iptables rules iptables -D OUTPUT -p UDP --dport $PORT -j ACCEPT iptables -D OUTPUT -p ALL -o $INTERFACE -j QUEUE iptables -D FORWARD -p ALL -o $INTERFACE -j QUEUE sleep 1 iptables -A INPUT -p UDP --sport $PORT -j ACCEPT # Allow control packets in iptables -A OUTPUT -p UDP --dport $PORT -j ACCEPT # Allow control packets out iptables -A OUTPUT -p ALL -o $INTERFACE -j QUEUE # All other traffic out via QUEUE target iptables -A FORWARD -p ALL -o $INTERFACE -j QUEUE # All other forwarded traffic via QUEUE target start-stop-daemon --start --pidfile $PIDFILE --make-pidfile --exec $BIN -- $ARGS echo "." ;; *) N=/etc/init.d/$NAME echo "Usage: $N start|stop|restart|force-reload" >&2 exit 1 ;; esac exit 0 ++++ ---- '''/etc/init.d/frottle-master''' ++++ #! /bin/sh # # Frottle Master init script by Dan Flett 2005 # #Put your Frottle Master interface here INTERFACE="eth2" #Change this to the port you are running Frottle on PORT=999 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin NAME=frottle CONF=/etc/frottle-master.conf BINDIR=/usr/local/bin BIN=$BINDIR/$NAME ARGS="-c $CONF -d" PIDFILE=/var/run/frottle-master.pid DESC="Frottle Master" test -x $BIN || exit 0 set -e case "$1" in start) echo -n "Starting $DESC " /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects # stop ICMP Redirects iptables -A INPUT -p UDP --dport $PORT -j ACCEPT # Allow control packets in iptables -A OUTPUT -p UDP --sport $PORT -j ACCEPT # Allow control packets out iptables -A OUTPUT -p ALL -o $INTERFACE -j QUEUE # All other traffic out via QUEUE target iptables -A FORWARD -p ALL -o $INTERFACE -j QUEUE # All other forwarded traffic via QUEUE target start-stop-daemon --start --pidfile $PIDFILE --make-pidfile --exec $BIN -- $ARGS echo "." ;; stop) echo -n "Stopping $DESC " PID=`cat $PIDFILE` PID1=`expr $PID + 1` PID2=`expr $PID + 2` PID3=`expr $PID + 3` kill $PID1 $PID2 $PID3 rm $PIDFILE # #Please check the below rules - I'm not sure this is how they work -- Dan # iptables -D INPUT -p UDP --dport $PORT -j ACCEPT #Delete iptables rules iptables -D OUTPUT -p UDP --sport $PORT -j ACCEPT iptables -D OUTPUT -p ALL -o $INTERFACE -j QUEUE iptables -D FORWARD -p ALL -o $INTERFACE -j QUEUE /bin/echo "1" > /proc/sys/net/ipv4/conf/all/accept_redirects # allow ICMP Redirects again echo "." ;; restart|force-reload) echo -n "Restarting $DESC " PID=`cat $PIDFILE` PID1=`expr $PID + 1` PID2=`expr $PID + 2` PID3=`expr $PID + 3` kill $PID1 $PID2 $PID3 rm $PIDFILE sleep 1 /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects # stop ICMP Redirects iptables -A INPUT -p UDP --dport $PORT -j ACCEPT # Allow control packets in iptables -A OUTPUT -p UDP --sport $PORT -j ACCEPT # Allow control packets out iptables -A OUTPUT -p ALL -o $INTERFACE -j QUEUE # All other traffic out via QUEUE target iptables -A FORWARD -p ALL -o $INTERFACE -j QUEUE # All other forwarded traffic via QUEUE target start-stop-daemon --start --pidfile $PIDFILE --make-pidfile --exec $BIN -- $ARGS echo "." ;; *) N=/etc/init.d/$NAME echo "Usage: $N start|stop|restart|force-reload" >&2 exit 1 ;; esac exit 0 ++++ These scripts seem to do the job of starting and stopping separate instances of Frottle in client and master mode. They just need a bit of polishing to stop multiple instances of the same mode - or at least - different PID files for different instances on different interfaces. It remains to be seen wether running two or more instances of Frottle (master and client) on port 999 will work in practice. Are you thinking of a box being Master on one network and a client on another? Because it is using UDP the communication is connectionless so multiple instances can share a port. Looking in the source the master thread listens on the port and the clients write to the specified port/IP Address of the master. So you caould get away with not changing the port except if you have two master instances on the same machine. The client does not open the specified port ratehr a random port is opened but it writes to the specified port on the master. The master will return messages to the originating IP Address and port. --[dna] I'm going to continue this discussion and outline how I want it to work on [MWRPFrottleDevDiscussion]. I've worked out that every instance of Frottle using port 999 will work just fine because I want each instance of Frottle to operate on a separate network interface - so there should never be a clash. Our big problem currently is the limitations of the IPTables QUEUE target - apparently you can't have a separately controllable QUEUE for each network interface in the one box. The IPTables MARK target may solve this issue, but Frottle would probably need to be modified to take advantage of it. I need to read up more on the QUEUE and MARK targets to see what they are capable of. --DanFlett ---- Back to [MelbWirelessRouterProject]