                            guessnet
                             README

Sections:
NOTES
INTRODUCING
MARKETING
TRIGGERING
BUILDING
MAINTAINING
TODO
DONE
LINKS

NEWS
====
Last updated 27 Oct 2005

INTRODUCING
===========
The guessnet program tries to guess the current network location by
performing tests such as making DHCP and ARP requests.

Please see the guessnet(8) manual page for usage information.

MARKETING
=========
In this section guessnet is discussed in comparison with other automagic
network configurers.

The following network configurers exist in Debian.  Numbers in
brackets are the number of votes each package had in popularity-
contest on 22 October 2004.

  * guessnet [25]
      Report current network environment
      - This can be used as an ifup mapping program to select configuration
        for the current environment
  * ifupdown [5710]
      Configure or deconfigure network
      - These are the standard Debian tools for configuring and deconfiguring
        a network interface
  * intuitively [3]
      Select network configuration for current environment
  * laptop-net [0, but 63 installed]
      Continually select network configuration for current environment
  * netenv [36]
      On boot, set environment variables to manually selected values
      - This can be used to switch between network configurations.
  * whereami [18]
      On boot, APM event, pcmcia event or command, clock state machine.
      Tests and actions are furnished that are useful for testing current
      environment and for configuring the network.  Incompatible with
      ifupdown.

Ifupdown does not work correctly if other utilities independently futz
with the low-level network configuration.  Therefore, any adequate
solution must be one that either replaces ifupdown entirely or else
cooperates with it somehow.  Of the above, only laptop-net and guessnet
do the latter.

Laptop-net is like a combination of ifplugd, intuitively and switchconf
rolled into one, except that it is better than such a combination
because it uses ifupdown to do low-level configuration, is better
integrated and has good documentation.

Guessnet is designed to integrate into ifupdown: it is a program that
"maps" the specified "physical interface" to the first "logical
interface" that it finds by scouting around.  One of the many advantages
of integrating with ifupdown is that ifupdown handles locking: only one
instance of if(up|down) can run at a time (and so ditto for its mapping
programs).  When using guessnet, ifplugd or waproamd and init and apmd
hook scripts can be configured to run ifdown and ifup, which calls
guessnet.

The following packages were referred to above:

  * ifplugd [141]
      Continually monitor iface for (pre|ab)sence of link beat
      - This can be used to trigger a configurer.
  * waproamd [33]
      Continually scan for access points and set encryption key
      according to the detected MAC or ESSID.

These packages were included in earlier releases of Debian but are now
obsolete.

  * divine
      Ancestor of intuitively
  * laptop-netconf
      Select network configuration for current environment

I have also found the following software that hasn't been packaged
for Debian.  For more information consult Freshmeat.net and/or Google.

  * bootprofile
      On boot, set environment variables to manually selected values
  * quickswitch
      On boot or command, set environment variables to manually selected values
  * FEWT Traveler
      Select network configuration
  * autonetconf
      Select network configuration for current environment
      - Trivial
  * TuX-Mobile
      Continually select network configuration for current environment
      - This one looks ambitious.  Documentation in Spanish.
      - GNOME app.
      - Vaporware.
  * aphopper
  * aphunter
      Continually associate to wireless access points
  * perlskan
      Scan for APs and log info with GPS data
  * Wellenreiter
      Scan for APs and display details
  * YaST
      SuSE's network configurator
      - http://sdb.suse.de/en/sdb/html/mmj_network80.html
  * netcfg
      Improved RedHat network configurer
      - http://netcfg.sourceforge.net/
  * NetworkManager
      Uses DBUS and HAL to set up network configuration
      - http://people.redhat.com/dcbw/NetworkManager

TRIGGERING
==========
Using ifupdown and guessnet one's interface will be reconfigured every
time it is upped with ifup.  To increase automation, one wants ifup to
be run on events such as (1) boot, (2) APM resume, (3) PCMCIA network
card insertion, (4) hotplug event, (5) establishment of network link,
(6) wireless event, (7) timer, (8) whim.

1.  boot
ifup is already run at boot time by /etc/init.d/networking to bring
up all interfaces defined as "auto".

2.  APM resume
You can add a hook script to /etc/apm/event.d to ifdown and ifup
interfaces on APM suspend and resume.

3.  PCMCIA network card insertion
The default /etc/pcmcia/network and /etc/pcmcia/network.opts conffiles
shipped in the pcmcia-cs package will cause cardmgr to ifup interfaces
on inserted non-CardBus PCMCIA cards and to ifdown interfaces on
ejected non-CardBus PCMCIA cards.  The ifup should be disabled
since we want to let the hotplug mechanism take care of network
configuration.  Simply put an "exit 0" line near the top of the 
"start" case in /etc/pcmcia/network.

As you know, cardmgr beeps once to signal that it has detected a new
PCMCIA card, and beeps a second time to indicate that it has
successfully configured the card.  If, previously, you had your system
configured so that the ifup was done by cardmgr via /etc/pcmcia/network
then you are accustomed to hearing the second cardmgr beep _after_ the
interface has been brought up.  If you are now letting hotplug bring
up the interface then you may hear the second cardmgr beep before or
during the configuration of the interface because cardmgr no longer
has to wait for network configuration to complete before it beeps.
If you really liked having a beep tell you that the interface is ready
to use then use ifplugd (see below), which beeps when it detects a
link beat and beeps again when it has configured the interface.

4.  hotplug event
Current Linux kernels run the hot plug handling program "hotplug"
when new adapters (include PCMCIA cards) are plugged in.  The current
default configuration of the hotplug package will cause ifup to be
called with "hotplug" specified as the logical interface name.  To
make use of this such that hot plug causes interfaces to be ifupped
after they become available, include the following stanza in
/etc/network/interfaces .

    mapping hotplug
        script echo

If you want to restrict ifup-on-hot-plug to a certain list of
interfaces then use a stanza like the following instead, listing the
interfaces you want to be ifupped on separate map lines.

    mapping hotplug
        script grep
        map eth0
        map eth2

Here eth0 and eth2 are the interfaces you want to be ifupped on
hot plug.  Any other interfaces will not be ifupped.

I don't recommend that this be done, however.  Read on.

5.  establishment of network link
Even better is to use ifplugd or waproamd to ifup and ifdown
interfaces for you according to whether, in the case of ifplugd and
a wired network interface, a network cable is plugged in or, in the
case of waproamd and a wireless network interface, an access point
is associated.  The ifplugd or waproamd daemon will call ifup when the
network adapter detects a link (presence of active network cable or
associated wireless access point) and ifdown when the link is broken
(cable disconnected or AP disassociated).

Ifplugd and waproamd can be configured to be started and stopped by
hotplug.

Ifplugd works better with some cards than with others.  You may find
that ifplugd is useless with yours.

If your wireless network traffic is encrypted then your wireless
networking adapter needs to be programmed with the encryption key.
Many adapters can store one or more keys in their nonvolatile memory
and will choose a key that allows them to associate.  If you make
use of this feature then once you have programmed the adapter no
system-side support is necessary.  If you do not have the benefit
of this feature then your system will need to be set up so that it
sets the encryption key each time the adapter is powered up.  The
console command for this is "iwconfig IFACE key ...".

The best way to set the key is to use waproamd.  Waproamd scans for
wireless networks and sets the encryption key according to the MAC
address or the ESSID of the detected access point.  E.g., suppose
your access point 00:62:a5:37:1e:67 requires the key 12345678901;
simply create a file /etc/waproamd/keys/00:62:a5:37:1e:67.wep 
containing the string "12345678901".

Using waproamd provides several benefits.  Waproamd can store any
number of keys, so you are not limited in the number of different
networks among which you can roam.  Waproamd works independently of
the other programs we have been discussing, but is designed to work
properly with ifplugd.  Waproamd takes care of setting required
keys; the setting of appropriate keys causes adapter association;
ifplugd notices association and calls ifup to bring up the interface.

6.  wireless event
You could use iwevent to trigger a call to (ifdown and) ifup on
certain wireless network events such as appearance or disappearance
of access points.

Unfortunately there is currently (in wireless-tools 26) a bug in
iwevent that makes it impossible to pipe the output of the program,
thus rendering it nearly useless for this purpose.

7.  timer
You could set up cron to run (ifdown and) ifup periodically.  (See
below).

8.  user's whim
The user can run (ifdown and) ifup any time to reconfigure all active
interfaces.

Note:  If you install the whereami package, make sure you remove
the file /etc/network/if-pre-up.d/whereami which is a faulty
attempt to hook whereami into ifup, even though whereami is
fundamentally incompatible with the standard ifupdown package.
Also make sure that whereami is not called on any of the events
mentioned above.

BUILDING
========
automake 1.9.6 was used.

MAINTAINING
===========

Enrico is the main maintainer of guessnet, but he isn't the best person for it:
he doesn't usually work with network protocols, he doesn't use all scan methods
and he uses a limited amount of hardware.

This means that Enrico could be good in gluing all the code together, but he
can't do a good job alone with making sure that everything works everywhere or
with implementing a fancy new scan method.  There is a need of more people with
different needs and skills to work together.

This section lists the various scan methods together with who is maintaining
them and their status.


'peer' scan
-----------

Maintained by Enrico and generally working, although one should send patches to
get new features in and not rely on Enrico's low-level networking skills :)


'pppoe' scan
------------

Currently unmaintained.  If you regularly use this, have a bit of technical
skills and want to take care of it, please contact enrico@enricozini.org.


'wifi' scans
------------

Currently unmaintained.

This is currently implemented using external scripts, which are officially
unmaintained besides some patch from Thomas Hood to fix the biggest issues.

The scripts are sometimes interacting badly with the rest of guessnet (they
bring the interface up and down while the rest of guessnet is doing the same).
The best long-term course of action would be to use libiw-dev to implement the
scripts' work inside guessnet.

It is also unclear what would be the role of guessnet and what would be the
role of waproamd.

If you regularly use this, have the needed technical skills and want to take
care of it, please contact enrico@enricozini.org.


'missing link' scan
-------------------

Maintained by Enrico, but not working in some hardware.  If you happen to have
a non-working interface, please help finding a patch.  More code to do
link-beat detection can be found in mii-tool and in ifplugd.


'dhcp' scan
-----------

Just drafted and unmaintained.  If you have a good understanding of the DHCP
protocol, please help in extending this.  Recognizing the DHCP server name in
the reply, for example, would be a very useful feature.


'script' scan
-------------

Maintained by Enrico.


TODO
====

 - Check out NetworkManager

 - Create a script to output an ifupdown configuration snippet out of the
   current network configuration:

     $ guessnet-mkconfig eth0 debconf
     iface debconf inet static
       address <current IP address>
       netmask <current netmask>
       broadcast <current broadcast>
       gateway <current gateway>
       test-peer <ip and mac of gateway>
     $ guessnet-mkconfig eth0 debconf peermachine
     <same results except for test-peer>
       test-peer <ip and mac of machine "peermachine">

 - Add an option to just dump configuration to stdout and exit, to be used
   to test configuration file parsers

 - Suggest ifplugd and suggest a high hysteresis

 - Wait for #238344 "unknown physical layer type 0x30f" to be solved
   (cannot reproduce anymore)

 - Render the libnet work-around optional, wrap it around preprocessor
   directives and set the directives in configure.ac

 - Consider #226031 "support for a --runcommand option"
 
 - It might be that Fabian's patch introduces this bug that guessnet can't kill
   child processes still running when the program should end

 - Make guessnet-scan try to get a dhcp lease, and if it succeeds, output an
   iface line with dhcp and a test-peer to the dhcp server
   (need to wait until the *damn* libnet1 fixes bug#180441 :(( )

 - Use tcpdump's produced packet matching code for having precise and optimized
   packet matching in the sniffer

 - Wish: it would be nice to have a macaddr-only detection mechanism, as
   coming up on the wrong ip on a network can sometimes be disruptive to
   others (i.e.  someone else already using the same ip addr).  I'm not
   sure what mechanism would underlie such a thing, tho.
   (Tony Godshall <togo@of.net>)

 - guessnet: Limit the scope of the program to Ethernet.  Whoever calls guessnet
   does it just to find out the correct profile for an Ethernet interface.  For
   detection on other kinds of interfaces, other programs can be made.

 - Add default tests according to the kind of logical interface defined
   in /e/n/i?

 - If multiple addresses or address/mac pairs are specified in a single
   test-peer line, they should all exist for the test to be true
   (opens the possibility of the same peer being specified in multiple lines,
   requiring to handle this in a smart way).

 - Bringing up and down the interface spawns children which could
   interfere with ProcessRunner (Should not do so, though, since iface_init
   and iface_shutdown are invoked when the ProcessRunner is not active)?

 - I'm open to better ideas on how to implement ProcessRunner.cc (see its
   FIXMEs)

 - Suggest ifupdown people to implement a zcip mode

 - wireless test needs to be integrated into guessnet proper.  The
   test-wireless script does ifconfig up and ifconfig down which is
   really terrible because guessnet runs many instances of the script
   in parallel.

DONE
====

 * Done in version 0.38
 
 + Applied patch from Jean-Damien Durand to get scripts with arguments to work
   again.

 
 * Done in version 0.36

 + Implemented peer test without destination IP, to test for the existance of
   physical interfaces with changing IP addresses.
 + Script scans now look for the script in /usr/share/guessnet/test if they are
   specified with relative paths.  It is easier to write in the config file,
   and it avoids scripts specified without an absolute path to be run relative
   to the current directory, which is bad.
 + Script scans now get a sane and clean PATH, which includes the script
   directory itself.
 
 
 * Done in version 0.35

 + Allow any number of spaces between "test" and the rest of the line
 + Complains if a line starts with "test(-|\s)" but it cannot be parsed by
   guessnet.


 * Done in version 0.30

 + Add happy bound checking when accessing packets
 + Add DHCP scan
    - DHCPINFORM, DHCPREQUEST (see dhcping for how to do it)
    - dhcpcd -d -c /dev/null -T ethp_0 -t 4
 + In case timeout happens and there are still multiple candidate profiles,
   return the default profile name


 * Done in version 0.29

 + Allow an extra "src <ip address>" for arp scans, to set the source IP when
   the peer doesn't answer DAD ARP packets
    + Implement in parser
    + Implement in scans
 + Add version info to --debug output
 + Create an example file for the ifupdown (or guessnet) configuration, to be
   shipped in /usr/share/doc/guessnet/examples


 * Done in version 0.28

--- 2004-03-31
 + Fixed debian/copyright file (#240791)
 + Removed ifexpr code (#240759)
 + Did not wait for timeout to get scan results
 + ScanBag: returns the last scan instead of defaultScan if there are no scan
   results (#240781)


 * Done in version 0.27

--- 2004-03-27
 + Really invoke the scan start routine
 + Taken working MII detection from ifplugd
 + Applied Lennart patches (#240387)

--- 2004-03-18
 + Implement tests as binary expression
   NO: it would be hard to evaluate a NOT ping
   Instead, implement the cases in which it makes sense to AND scans: for
   example, allow multiple peer data to be specified in a test-peer, and treat
   them as ANDed together
    + Even, use ambiguity:
       - save each profile with the list of scans
       - as soon as a scan succeeds, remove it
       - the first profile that remains without scans nor other more specific
	 candidates (e.g. dhcp, dhcp+arp) wins
       - on timeout, in case a profile succeeds but there are more specific
	 candidates, forget about them and output the succeeded scan.
 + Debug the strange exception problem in test-netsender (bug#235591)
    - If I don't do a cancel, everything is fine
    - If I don't do delete impl, sometimes aborts
    - If I don't do libnet_destroy, sometimes aborts
    - Replace cancel with a quit request
 + Don't wait for sigchild if ProcessRunner (doesn't work on my system) but
   busy-wait for events with a 10msec pause between iterations (can't come up
   with anything better)

--- 2004-03-16
 + Start test-netsender.cc
 + IFace::initBroadcast: when initializing for 0.0.0.0, IFP_VALID_* are
   probably not accepted.  Search ifconfig sources on how to do that

--- 2004-03-15
 + Start test-iface.cc

--- 2004-01-21
 + Dedicate next release to Alberto Gonzalez Iniesta
 + Don't call ifconfig: directly use interface configuration routines from
   laptop-net (also works around the libnet bug)
 + Include the patch from Chris Hanson to work around libnet's bug

 
 * Done in version 0.26

--- 2004-01-07
 + Use libnet_adv_cull_packet instead of libnet_pblock_coalesce
 + Solve #225221 (FTBFS with patch from Joey)
 + Solve #224894 (segfault on "default:")
   The environments called get() in the constructor, which of course would have
   tried to dereference 0
 + Solve #224910 (Do not enforce UID to be 0, but print a note about uid not
   being 0 when catching fatal exceptions)
 + Solve #224893 by supporting an optional guessnet[0-9]* in front of lines
 + Put an optional 'guessnet[0-9]* ' in front of everything
   Solves #224893 (using 'guessnet' option instead of 'test' in interfaces file)
 + Put an optional arbitary number after test
 + Put the optional dash after test[0-9]*
 + Reintroduce the dash in test-stuff (ifupdown complains about duplicate
   first-words even in unrecognized lines)
 + Document that if no logical interfaces are given on stdin in ifupdown mode,
   all those that are found are tried
 + Document test-missing-cable as test-missing-cable please (and .+ for what
   it matters)
 + Do not mention ethernet in the documentation anymore
    + manpage
    + README
    + README.Debian
    + debian/control
 + Document why numbers and garbage after test-missing-cable
 + Document the optional guessnet name in ifupdown config lines
 + Document the ifupdown wishlist bugs of guessnet interest in README.Debian
 + Apply the changes in #224888
 + Document that multiple test- things are "or-ed" together, not "and-ed"
 + Add a pppoe scan taking the code from one of the ifupdown-roam scripts
 + Add a scripts directory
 + Add experimental support for wireless scans by transparently running
   /usr/share/guessnet/test-wifi-* scripts
 + Print a warning about "guessnet default" being obsolete if it is used in
   ifupdown mode
 + Added some preliminary test scripts for the parser
 

* Done in version 0.25

 + logic_error creating a string with a null when running guessnet -i (or maybe
   also normal guessnet) on an interface who's up but not initialized yet)


* Done in version 0.24

--- 2003-12-21
 + Configuration file: change "test-stuff" in "test stuff".  Allow for both
   syntaxes.
 + Allow for specifying test-peer scans without a macaddress.  If no macaddress
   is provided, when and PARP reply is received it should not be tested for
   MACaddress match, but just make the test succeed.  In this case it's like a
   ping scan.
 + Make sure that we use forward arp instead of reverse arp


* Done in version 0.23 "Who does not die sees himself again"

--- 2003-12-20
 + Implemented two different environments for the two different work modes
   (normal and ifupdown)
 + Port to libnet1
 + Encapsulate configuration parsing, and instantiate the right parser through
   a factory class that checks commandline switches and whatever
 + If there are no profiles given in stdin in ifupdown mode, assume they are
   all enabled
 + Integrate the simple patch from the BTS (thank you Fabian Knittel!)
 + If the interface detects no link beat, output a profile "none".  Add a
   switch to change its name and to turn the feature off for interfaces that do
   not support link beat detection.


 + Open a project on a development server like Savannah, SourceForge or Alioth.
   (Chosen Alioth)


* Done in version 0.21

--- 2003-05-26
 + In ifupdown mode, read from stdin all the commandline parameters, not just
   the --default equivalent
 + Document the new peer and commandline-in-map-lines syntax
 + Guess the local network address and the gateway address through network
   sniffing:
    + build a table with source and target IPs and MACs of IP packets that pass
      thru the network: in the common case, you have packets from and to the
      local net, and packets from/to outside with the gateway MAC address in
      the side of the external IP.  After some sniffing, it should be easy to
      distinguish the gateway from the other machines, and consequently the
      local network address
    + use this scheme in an external application that scans for a gateway and
      prints a guessnet scan definition to be put in the config file


* Done in version 0.20

--- 2003-05-25
 + Removed redundant documentation from the README, and added a line pointing
   to the manpage for further documentation
 + The new peer syntax is not parsed well (it misses all key-value pairs except
   the first)
 + Replace -V with -vv (or with --debug) and let -V work as --version
 + Remove dependancy on libpopt
 + Use the code from netplugd to wait for an interface to come up instead of
   using init-timeout.  Use init-timeout only to avoid waiting indefinitely in
   case of problems.
--- 2003-05-19
 + NetSender, NetWatcher and ProcessRunner didn't increment the Impl reference
   count in their plain constructor


* Done in version 0.19

--- 2003-05-16
 + Change the parser to allow a syntax like:
    + test-peer ip 1.2.3.4 mac a:b:c:d:e:F service www
	     and consider only the parameters that are needed
    + test-command commandline
 + The interface default in ifupdown mode should be listed in a line as:
   default: name
 + The test to see if an interface is up does not work, and if the interface is
   down, pcap_next returns 0 because it's not been brought up
    + the interface keeps existing in /proc/net/dev even if it's down.
    + use the check from netplugd


* Done in version 0.18

--- 2003-05-10
 + Ship guessnet with a guessnet-ifupdown link
 + Do not scan getppid for ifupdown mode, but check argv0.
 + Prefix the ifupdown guessnet lines with "guessnet "
 + manpage: change the program description, since now it doesn't just use ARP probes
 + manpage: document -i behaviour
 + manpage: document script scan behaviour
 + Make a singleton environment class to hold run-time parameters (interface,
   verbosity...)
 + Export NAME=tag and IFACE=interface in the environment of child scripts
 + [Thomas Hood] you need to add an option to set the configuration file.  With
   the [current] syntax, you can't specify a config file unless you also
   specify an ethernet interface
 + ChildProcess: make more versions of fork, especially a simple one that does
   not try to do magic with file descriptors
 + In ifupdown mode, read the list of profiles to try from stdin, so that it
   won't always try every possible stanza found in /etc/network/interfaces
 + guessnet hangs if no candidates are found in input
    + Locks waiting mutex in killall at runner.shutdown()
 + guessnet hangs if only a script /bin/false candidate is found in input


* Done in version 0.17

--- 2003-05-09
 * Introduce other detection ideas:
    + External script
 + Rename --use-interfaces to --use-ifupdown


* Older releases

---
 + Add a manpage
 + Use a different timeout if the interface is not found up but is brought up
   by guessnet, since in that case it might require more time to initialize
   itself
 + Audit the code clearing endianness issues
 + Port to libnet1
 = Check what is the difference between guessnet and the arpfind script found
   in the scripts directory of newer whereami, that do
   arping -f -w1 -D -I $INTERFACE $REMOTEIP | grep -e $REMOTEMAC
   Example:
	marvin:~# arping -f -w1 -D -I eth0 192.168.1.1
	ARPING 192.168.1.1 from 0.0.0.0 eth0
	Unicast reply from 192.168.1.1 [00:01:02:03:04:05] for 192.168.1.1 [00:0A:0B:0C:0D:0E] 0.741ms
	Sent 1 probes (1 broadcast(s))
	Received 1 response(s)

   If they are the same, we could get rid of guessnet and write a shellscript
   around arping to do the same.
    = After the redesign, a script cannot do what guessnet is doing
 + Backport to libnet0 (*&%^%$^!!)
 + See if the broadcast IP address can be used as the local IP address
   No, but 0.0.0.0 can (see arping -D manpage)
 + Implement the new config file syntax
    + <profile-name> <method> <parms...>
    - Example:
      casa peer 192.168.1.1 01:02:03:04:05:06
      uni dhcp <dhcp-data>
      otherplace script /usr/local/bin/detect-otherplace
 + Hervé Eychenne
   > So, the pb is that you MUST specify the interface when using -v and -V
   > options, whereas you don't have to when specifying no parameter.

LINKS
=====

 - http://www.networksorcery.com/enp/protocol/
