2 package nl.openfortress.android6bed4;
5 import java.net.NetworkInterface;
6 import java.net.InetAddress;
7 import java.net.SocketException;
8 import java.util.Enumeration;
9 import java.util.Collection;
10 import java.util.Vector;
13 import android.content.BroadcastReceiver;
14 import android.content.Intent;
15 import android.content.IntentFilter;
16 import android.content.Context;
17 import android.net.ConnectivityManager;
20 /* The EventListener class picks up signals from the Android OS,
21 * and processes them internally.
23 * Upon receiving BOOT_COMPLETED, it will see if the user wishes
24 * to start 6bed4 at boot time. Since this presents a popup, this
25 * is a setting that must be explicitly configured. More details:
26 * http://stackoverflow.com/questions/5051687/broadcastreceiver-not-receiving-boot-completed
28 * Upon receiving CONNECTIVITY_ACTION, it will see if there is a
29 * default route over IPv6 that does not a 6bed4 address. See:
30 * http://stackoverflow.com/questions/5276032/connectivity-action-intent-recieved-twice-when-wifi-connected
31 * http://developer.android.com/reference/android/net/ConnectivityManager.html
33 class EventListener extends BroadcastReceiver {
35 private TunnelService netcfg_target;
37 public void onReceive (Context ctx, Intent intent) {
38 String act = intent.getAction ();
40 if (act.equals (ConnectivityManager.CONNECTIVITY_ACTION)) {
42 // The Network Configuration has changed.
43 // The NetworkInfo for the affected network is sent as an extra
44 if (netcfg_target == null) {
48 Collection <byte[]> ipv6list = new Vector <byte[]> ();
49 Enumeration <NetworkInterface> nif_iter = NetworkInterface.getNetworkInterfaces ();
50 while (nif_iter.hasMoreElements ()) {
51 NetworkInterface nif = nif_iter.nextElement ();
54 Enumeration <InetAddress> adr_iter = nif.getInetAddresses ();
55 while (adr_iter.hasMoreElements ()) {
56 InetAddress adr = adr_iter.nextElement ();
57 if (adr.isLoopbackAddress () || adr.isLinkLocalAddress () || adr.isAnyLocalAddress () || adr.isSiteLocalAddress () || adr.isMulticastAddress ()) {
60 byte ipv6addr [] = adr.getAddress ();
61 if (ipv6addr.length != 16) {
64 ipv6list.add (ipv6addr);
67 } catch (SocketException se) {
70 // Now tell the tunnel service about ipv6list
71 netcfg_target.notify_ipv6_addresses (ipv6list);
73 } catch (SocketException se) {
77 } else if (act.equals (Intent.ACTION_BOOT_COMPLETED)) {
79 // The system has finished booting. Consider starting 6bed4
80 // at this point (if the user is willing to deal with the popup
81 // from the VPN toolkit at this point.
82 Intent main = new Intent (Intent.ACTION_MAIN);
83 main.addCategory (Intent.CATEGORY_HOME);
84 ctx.startActivity (main);
89 /* Register this object as a network monitor reporting to the
90 * given TunnelService object when the set of local IPv6 addresses
91 * changes. Note that the TunnelService is supposed to be smart
92 * enough to avoid endless loops; the monitor simply reports if a
93 * notification comes in, even if it is caused by 6bed4.
95 public void register_network_monitor (TunnelService target) {
96 if (netcfg_target != null) {
97 unregister_network_monitor ();
99 netcfg_target = target;
100 IntentFilter intflt = new IntentFilter (Context.CONNECTIVITY_SERVICE);
101 /* TODO -- how to get to the current context?!?
102 Context ctx = getApplicationContext ();
103 ctx.registerReceiver (this, intflt);
108 /* Unregister this object as a network monitor reporting to a
109 * once-setup TunnelService.
111 public void unregister_network_monitor () {
112 //TODO// how to unregister for CONNECTIVITY_SERVICE broadcasts?
113 netcfg_target = null;