From 46fd086337a8765f72c9a7178e4d38571e5f7719 Mon Sep 17 00:00:00 2001 From: M66B Date: Sat, 30 Jan 2016 14:26:30 +0100 Subject: [PATCH] Block/allow hosts UI --- app/app.iml | 1 - .../eu/faircode/netguard/AccessAdapter.java | 29 ++++- .../eu/faircode/netguard/ActivityLog.java | 2 +- .../eu/faircode/netguard/DatabaseHelper.java | 77 +++++++++++-- .../faircode/netguard/ExpandedListView.java | 19 ++++ .../java/eu/faircode/netguard/LogAdapter.java | 19 ++++ .../eu/faircode/netguard/RuleAdapter.java | 101 ++++++++++++++++-- .../eu/faircode/netguard/SinkholeService.java | 90 ++++++++++++---- app/src/main/jni/netguard/netguard.c | 2 + .../{ip_allowed.xml => host_allowed.xml} | 0 .../{ip_blocked.xml => host_blocked.xml} | 0 app/src/main/res/drawable/ip.xml | 5 - app/src/main/res/layout/access.xml | 14 +-- app/src/main/res/layout/logview.xml | 1 - app/src/main/res/layout/rule.xml | 41 ++++++- app/src/main/res/menu/access.xml | 16 +++ app/src/main/res/values/strings.xml | 3 + 17 files changed, 364 insertions(+), 56 deletions(-) rename app/src/main/res/drawable/{ip_allowed.xml => host_allowed.xml} (100%) rename app/src/main/res/drawable/{ip_blocked.xml => host_blocked.xml} (100%) delete mode 100644 app/src/main/res/drawable/ip.xml create mode 100644 app/src/main/res/menu/access.xml diff --git a/app/app.iml b/app/app.iml index c8002dfb..6e13ec56 100644 --- a/app/app.iml +++ b/app/app.iml @@ -98,7 +98,6 @@ - diff --git a/app/src/main/java/eu/faircode/netguard/AccessAdapter.java b/app/src/main/java/eu/faircode/netguard/AccessAdapter.java index ab7abc64..85548cfb 100644 --- a/app/src/main/java/eu/faircode/netguard/AccessAdapter.java +++ b/app/src/main/java/eu/faircode/netguard/AccessAdapter.java @@ -1,12 +1,31 @@ package eu.faircode.netguard; +/* + This file is part of NetGuard. + + NetGuard is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NetGuard is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NetGuard. If not, see . + + Copyright 2015-2016 by Marcel Bokhorst (M66B) +*/ + import android.content.Context; import android.database.Cursor; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.CheckBox; import android.widget.CursorAdapter; +import android.widget.ImageView; import android.widget.TextView; import java.text.SimpleDateFormat; @@ -42,13 +61,15 @@ public class AccessAdapter extends CursorAdapter { // Get views TextView tvTime = (TextView) view.findViewById(R.id.tvTime); - CheckBox cbBlock = (CheckBox) view.findViewById(R.id.cbBlock); + ImageView ivBlock = (ImageView) view.findViewById(R.id.ivBlock); final TextView tvDest = (TextView) view.findViewById(R.id.tvDest); // Set values tvTime.setText(new SimpleDateFormat("HH:mm:ss").format(time)); - cbBlock.setVisibility(block < 0 ? View.INVISIBLE : View.VISIBLE); - cbBlock.setChecked(block > 0); + if (block < 0) + ivBlock.setImageDrawable(null); + else + ivBlock.setImageResource(block > 0 ? R.drawable.host_blocked : R.drawable.host_allowed); tvDest.setText(daddr + (dport > 0 ? ":" + dport : "")); } } diff --git a/app/src/main/java/eu/faircode/netguard/ActivityLog.java b/app/src/main/java/eu/faircode/netguard/ActivityLog.java index f896f114..09552331 100644 --- a/app/src/main/java/eu/faircode/netguard/ActivityLog.java +++ b/app/src/main/java/eu/faircode/netguard/ActivityLog.java @@ -363,7 +363,7 @@ public class ActivityLog extends AppCompatActivity implements SharedPreferences. new AsyncTask() { @Override protected Object doInBackground(Object... objects) { - dh.clear(); + dh.clearLog(); if (prefs.getBoolean("pcap", false)) { SinkholeService.setPcap(null, false); pcap_file.delete(); diff --git a/app/src/main/java/eu/faircode/netguard/DatabaseHelper.java b/app/src/main/java/eu/faircode/netguard/DatabaseHelper.java index 61ba345c..aac1dc51 100644 --- a/app/src/main/java/eu/faircode/netguard/DatabaseHelper.java +++ b/app/src/main/java/eu/faircode/netguard/DatabaseHelper.java @@ -1,5 +1,24 @@ package eu.faircode.netguard; +/* + This file is part of NetGuard. + + NetGuard is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NetGuard is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NetGuard. If not, see . + + Copyright 2015-2016 by Marcel Bokhorst (M66B) +*/ + import android.content.ContentValues; import android.content.Context; import android.database.Cursor; @@ -9,7 +28,6 @@ import android.util.Log; import java.io.File; import java.util.ArrayList; -import java.util.Date; import java.util.List; public class DatabaseHelper extends SQLiteOpenHelper { @@ -19,8 +37,8 @@ public class DatabaseHelper extends SQLiteOpenHelper { private static final int DB_VERSION = 11; private static boolean once = true; - private static List logChangedListeners = new ArrayList(); - private static List accessChangedListeners = new ArrayList(); + private static List logChangedListeners = new ArrayList<>(); + private static List accessChangedListeners = new ArrayList<>(); private Context mContext; @@ -229,7 +247,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { return this; } - public DatabaseHelper clear() { + public DatabaseHelper clearLog() { synchronized (mContext.getApplicationContext()) { SQLiteDatabase db = this.getReadableDatabase(); db.delete("log", null, new String[]{}); @@ -248,14 +266,16 @@ public class DatabaseHelper extends SQLiteOpenHelper { public Cursor getLog() { SQLiteDatabase db = this.getReadableDatabase(); - String query = "SELECT ID AS _id, * FROM log"; + String query = "SELECT ID AS _id, *"; + query += " FROM log"; query += " ORDER BY time DESC"; return db.rawQuery(query, new String[]{}); } public Cursor searchLog(String find) { SQLiteDatabase db = this.getReadableDatabase(); - String query = "SELECT ID AS _id, * FROM log"; + String query = "SELECT ID AS _id, *"; + query += " FROM log"; query += " WHERE daddr LIKE ? OR uid LIKE ?"; query += " ORDER BY time DESC"; return db.rawQuery(query, new String[]{"%" + find + "%", "%" + find + "%"}); @@ -297,13 +317,56 @@ public class DatabaseHelper extends SQLiteOpenHelper { return this; } + public DatabaseHelper setAccess(long id, int uid, int block) { + synchronized (mContext.getApplicationContext()) { + SQLiteDatabase db = this.getWritableDatabase(); + + ContentValues cv = new ContentValues(); + cv.put("block", block); + + if (db.update("access", cv, "ID = ?", new String[]{Long.toString(id)}) != 1) + Log.e(TAG, "Set access failed"); + + for (AccessChangedListener listener : accessChangedListeners) + try { + listener.onChanged(uid); + } catch (Throwable ex) { + Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); + } + } + + return this; + } + + public DatabaseHelper clearAccess(int uid) { + synchronized (mContext.getApplicationContext()) { + SQLiteDatabase db = this.getReadableDatabase(); + db.delete("access", "uid = ?", new String[]{Integer.toString(uid)}); + } + + for (AccessChangedListener listener : accessChangedListeners) + try { + listener.onChanged(uid); + } catch (Throwable ex) { + Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); + } + + return this; + } + public Cursor getAccess(int uid) { SQLiteDatabase db = this.getReadableDatabase(); - String query = "SELECT ID AS _id, * FROM access WHERE uid = ?"; + String query = "SELECT ID AS _id, *"; + query += " FROM access WHERE uid = ?"; query += " ORDER BY time DESC"; return db.rawQuery(query, new String[]{Integer.toString(uid)}); } + public Cursor getAccess() { + SQLiteDatabase db = this.getReadableDatabase(); + return db.query("access", new String[]{"uid", "daddr", "dport", "block"}, "block >= 0", null, null, null, null); + } + public void addLogChangedListener(LogChangedListener listener) { logChangedListeners.add(listener); } diff --git a/app/src/main/java/eu/faircode/netguard/ExpandedListView.java b/app/src/main/java/eu/faircode/netguard/ExpandedListView.java index 691fd699..d7896516 100644 --- a/app/src/main/java/eu/faircode/netguard/ExpandedListView.java +++ b/app/src/main/java/eu/faircode/netguard/ExpandedListView.java @@ -1,5 +1,24 @@ package eu.faircode.netguard; +/* + This file is part of NetGuard. + + NetGuard is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NetGuard is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NetGuard. If not, see . + + Copyright 2015-2016 by Marcel Bokhorst (M66B) +*/ + import android.content.Context; import android.util.AttributeSet; import android.widget.ListView; diff --git a/app/src/main/java/eu/faircode/netguard/LogAdapter.java b/app/src/main/java/eu/faircode/netguard/LogAdapter.java index 383b805c..42b40211 100644 --- a/app/src/main/java/eu/faircode/netguard/LogAdapter.java +++ b/app/src/main/java/eu/faircode/netguard/LogAdapter.java @@ -1,5 +1,24 @@ package eu.faircode.netguard; +/* + This file is part of NetGuard. + + NetGuard is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NetGuard is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NetGuard. If not, see . + + Copyright 2015-2016 by Marcel Bokhorst (M66B) +*/ + import android.content.Context; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; diff --git a/app/src/main/java/eu/faircode/netguard/RuleAdapter.java b/app/src/main/java/eu/faircode/netguard/RuleAdapter.java index 7d4d7907..d499e504 100644 --- a/app/src/main/java/eu/faircode/netguard/RuleAdapter.java +++ b/app/src/main/java/eu/faircode/netguard/RuleAdapter.java @@ -22,10 +22,13 @@ package eu.faircode.netguard; import android.Manifest; import android.annotation.TargetApi; import android.app.Activity; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.TypedArray; +import android.database.Cursor; import android.graphics.Color; import android.graphics.Rect; import android.net.Uri; @@ -36,9 +39,11 @@ import android.support.v7.widget.RecyclerView; import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.TouchDelegate; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -48,6 +53,7 @@ import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; +import android.widget.PopupMenu; import android.widget.TextView; import com.squareup.picasso.Picasso; @@ -107,6 +113,7 @@ public class RuleAdapter extends RecyclerView.Adapter im public Button btnLaunch; public ListView lvAccess; + public ImageButton btnClearAccess; public TextView tvStatistics; public ViewHolder(View itemView) { @@ -146,6 +153,7 @@ public class RuleAdapter extends RecyclerView.Adapter im btnLaunch = (Button) itemView.findViewById(R.id.btnLaunch); lvAccess = (ListView) itemView.findViewById(R.id.lvAccess); + btnClearAccess = (ImageButton) itemView.findViewById(R.id.btnClearAccess); tvStatistics = (TextView) itemView.findViewById(R.id.tvStatistics); final View wifiParent = (View) cbWifi.getParent(); @@ -417,11 +425,26 @@ public class RuleAdapter extends RecyclerView.Adapter im holder.btnClear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - holder.cbWifi.setChecked(rule.wifi_default); - holder.cbOther.setChecked(rule.other_default); - holder.cbScreenWifi.setChecked(rule.screen_wifi_default); - holder.cbScreenOther.setChecked(rule.screen_other_default); - holder.cbRoaming.setChecked(rule.roaming_default); + new AlertDialog.Builder(context) + .setTitle(R.string.msg_sure) + .setCancelable(true) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + holder.cbWifi.setChecked(rule.wifi_default); + holder.cbOther.setChecked(rule.other_default); + holder.cbScreenWifi.setChecked(rule.screen_wifi_default); + holder.cbScreenOther.setChecked(rule.screen_other_default); + holder.cbRoaming.setChecked(rule.roaming_default); + } + }) + .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Do nothing + } + }) + .create().show(); } }); @@ -447,10 +470,72 @@ public class RuleAdapter extends RecyclerView.Adapter im }); if (rule.expanded) { - AccessAdapter adapter = new AccessAdapter(context, dh.getAccess(rule.info.applicationInfo.uid)); - holder.lvAccess.setAdapter(adapter); - } else + final AccessAdapter badapter = new AccessAdapter(context, dh.getAccess(rule.info.applicationInfo.uid)); + + holder.lvAccess.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, final int bposition, long bid) { + Cursor cursor = (Cursor) badapter.getItem(bposition); + final long id = cursor.getLong(cursor.getColumnIndex("ID")); + final String daddr = cursor.getString(cursor.getColumnIndex("daddr")); + final int dport = (cursor.isNull(cursor.getColumnIndex("dport")) ? -1 : cursor.getInt(cursor.getColumnIndex("dport"))); + + PopupMenu popup = new PopupMenu(context, view); + popup.inflate(R.menu.access); + popup.getMenu().findItem(R.id.menu_host).setTitle(daddr + (dport > 0 ? ":" + dport : "")); + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + switch (menuItem.getItemId()) { + case R.id.menu_allow: + dh.setAccess(id, rule.info.applicationInfo.uid, 0); + SinkholeService.reload(null, "allow host", context); + return true; + case R.id.menu_block: + dh.setAccess(id, rule.info.applicationInfo.uid, 1); + SinkholeService.reload(null, "block host", context); + return true; + case R.id.menu_clear: + dh.setAccess(id, rule.info.applicationInfo.uid, -1); + SinkholeService.reload(null, "clear host", context); + return true; + } + return false; + } + }); + + popup.show(); + } + }); + + holder.lvAccess.setAdapter(badapter); + } else { holder.lvAccess.setAdapter(null); + holder.lvAccess.setOnItemClickListener(null); + } + + holder.btnClearAccess.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + new AlertDialog.Builder(context) + .setTitle(R.string.msg_sure) + .setCancelable(true) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dh.clearAccess(rule.info.applicationInfo.uid); + } + }) + .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Do nothing + } + }) + .create().show(); + } + }); // Traffic statistics holder.tvStatistics.setText(context.getString(R.string.msg_mbday, rule.upspeed, rule.downspeed)); diff --git a/app/src/main/java/eu/faircode/netguard/SinkholeService.java b/app/src/main/java/eu/faircode/netguard/SinkholeService.java index 1be88ada..4559bfd6 100644 --- a/app/src/main/java/eu/faircode/netguard/SinkholeService.java +++ b/app/src/main/java/eu/faircode/netguard/SinkholeService.java @@ -31,6 +31,7 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -74,6 +75,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.TreeMap; @@ -94,8 +96,9 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS private Object subscriptionsChangedListener = null; private ParcelFileDescriptor vpn = null; - private HashMap mapDomainBlocked = new HashMap<>(); - private HashMap mapUidAllowed = new HashMap<>(); + private Map mapHostsBlocked = new HashMap<>(); + private Map mapUidAllowed = new HashMap<>(); + private Map> mapUidIPFilters = new HashMap<>(); private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; @@ -649,7 +652,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS if (packet.uid > 0) dh.updateAccess(packet, rr == null ? null : rr.QName); - else + else if (packet.dport != 53) Log.w(TAG, "Unknown application packet=" + packet); dh.close(); @@ -795,8 +798,10 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS Log.i(TAG, "Start native log=" + log + " filter=" + filter); - // Prepare allowed/blocked lists - prepareAllowed(listAllowed); + // Prepare rules + prepareUidAllowed(listAllowed); + prepareHostsBlocked(); + prepareUidIPFilters(); if (log || filter) { int prio = Integer.parseInt(prefs.getString("loglevel", Integer.toString(Log.INFO))); @@ -809,15 +814,17 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS jni_stop(vpn.getFd(), clear); } - private void prepareAllowed(List listAllowed) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SinkholeService.this); - boolean use_hosts = prefs.getBoolean("use_hosts", false); - + private void prepareUidAllowed(List listAllowed) { mapUidAllowed.clear(); for (Rule rule : listAllowed) mapUidAllowed.put(rule.info.applicationInfo.uid, true); + } - mapDomainBlocked.clear(); + private void prepareHostsBlocked() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SinkholeService.this); + boolean use_hosts = prefs.getBoolean("use_hosts", false); + + mapHostsBlocked.clear(); if (use_hosts) { File hosts = new File(getFilesDir(), "hosts.txt"); BufferedReader br = null; @@ -832,7 +839,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS if (line.length() > 0) { String[] words = line.split("\\s+"); if (words.length == 2) - mapDomainBlocked.put(words[1], true); + mapHostsBlocked.put(words[1], true); else Log.i(TAG, "Invalid hosts file line: " + line); } @@ -851,6 +858,42 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS } } + private void prepareUidIPFilters() { + mapUidIPFilters.clear(); + + DatabaseHelper dh = null; + try { + dh = new DatabaseHelper(SinkholeService.this); + Cursor cursor = dh.getAccess(); + int colUid = cursor.getColumnIndex("uid"); + int colDAddr = cursor.getColumnIndex("daddr"); + int colDPort = cursor.getColumnIndex("dport"); + int colBlock = cursor.getColumnIndex("block"); + while (cursor.moveToNext()) { + int uid = cursor.getInt(colUid); + String daddr = cursor.getString(colDAddr); + int dport = cursor.isNull(colDPort) ? -1 : cursor.getInt(colDPort); + boolean block = (cursor.getInt(colBlock) > 0); + if (!mapUidIPFilters.containsKey(uid)) + mapUidIPFilters.put(uid, new HashMap()); + try { + for (InetAddress iaddr : InetAddress.getAllByName(daddr)) { + String addr = iaddr.toString() + "/" + dport; + addr = addr.substring(addr.indexOf('/') + 1); + Log.i(TAG, "Set filter " + daddr + " " + addr + "=" + block); + mapUidIPFilters.get(uid).put(addr, block); + } + } catch (UnknownHostException ex) { + Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); + } + } + cursor.close(); + + } finally { + dh.close(); + } + } + private List getAllowedRules(List listRule) { List listAllowed = new ArrayList<>(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); @@ -979,7 +1022,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS // Called from native code private boolean isDomainBlocked(String name) { - boolean blocked = (mapDomainBlocked.containsKey(name) && mapDomainBlocked.get(name)); + boolean blocked = (mapHostsBlocked.containsKey(name) && mapHostsBlocked.get(name)); return blocked; } @@ -987,16 +1030,27 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS private boolean isAddressAllowed(Packet packet) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + packet.allowed = false; if (packet.protocol == 6 /* TCP */ || packet.protocol == 17 /* UDP */) { if (prefs.getBoolean("filter", false)) { if (packet.uid <= 0) // unknown, root packet.allowed = true; - else - packet.allowed = (mapUidAllowed.containsKey(packet.uid) && mapUidAllowed.get(packet.uid)); - } else - packet.allowed = false; - } else - packet.allowed = false; + else { + boolean filtered = false; + if (mapUidIPFilters.containsKey(packet.uid)) { + String addr = packet.daddr + "/" + packet.dport; + if (mapUidIPFilters.get(packet.uid).containsKey(addr)) { + filtered = true; + packet.allowed = !mapUidIPFilters.get(packet.uid).get(addr); + Log.i(TAG, "Filtering " + addr + " allowed=" + packet.allowed); + } + } + + if (!filtered) + packet.allowed = (mapUidAllowed.containsKey(packet.uid) && mapUidAllowed.get(packet.uid)); + } + } + } if (prefs.getBoolean("log", false)) logPacket(packet); diff --git a/app/src/main/jni/netguard/netguard.c b/app/src/main/jni/netguard/netguard.c index f18eb0c1..db8531cf 100644 --- a/app/src/main/jni/netguard/netguard.c +++ b/app/src/main/jni/netguard/netguard.c @@ -1220,6 +1220,8 @@ void handle_ip(const struct arguments *args, const uint8_t *pkt, const size_t le else if (protocol == IPPROTO_TCP) handle_tcp(args, pkt, length, payload, uid); } + else + log_android(ANDROID_LOG_DEBUG, "Address %s/%u syn %d not allowed", dest, dport, syn); #ifdef PROFILE_EVENTS gettimeofday(&end, NULL); diff --git a/app/src/main/res/drawable/ip_allowed.xml b/app/src/main/res/drawable/host_allowed.xml similarity index 100% rename from app/src/main/res/drawable/ip_allowed.xml rename to app/src/main/res/drawable/host_allowed.xml diff --git a/app/src/main/res/drawable/ip_blocked.xml b/app/src/main/res/drawable/host_blocked.xml similarity index 100% rename from app/src/main/res/drawable/ip_blocked.xml rename to app/src/main/res/drawable/host_blocked.xml diff --git a/app/src/main/res/drawable/ip.xml b/app/src/main/res/drawable/ip.xml deleted file mode 100644 index cb2d33d5..00000000 --- a/app/src/main/res/drawable/ip.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/access.xml b/app/src/main/res/layout/access.xml index ab7ebcb5..ae3711cd 100644 --- a/app/src/main/res/layout/access.xml +++ b/app/src/main/res/layout/access.xml @@ -14,15 +14,11 @@ android:textAppearance="@android:style/TextAppearance.Material.Small" android:textSize="12sp" /> - - + + + + + + android:layout_marginTop="4dp" + android:text="@string/title_precedence" + android:textAppearance="@android:style/TextAppearance.Material.Small" + android:textStyle="italic" /> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/access.xml b/app/src/main/res/menu/access.xml new file mode 100644 index 00000000..40d3fd21 --- /dev/null +++ b/app/src/main/res/menu/access.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b355eb10..9feed91d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -116,12 +116,15 @@ Since NetGuard has no internet permission, you know your internet traffic is not Using filtering will cause Android to attribute data and power usage to NetGuard - Android assumes the data and power are being used by NetGuard, rather than the original applications Traffic logging is disabled, use the switch above to enable logging. Traffic logging might result in extra battery usage. + Conditions Allow Wi-Fi when screen is on Allow mobile when screen is on Block when roaming is disabled has no internet permission Start application + Access + Access rules take precedence over other rules Rate Allow Block