summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-07-27 05:00:48 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-07-27 05:00:48 +0000
commit813c1e1d6d2ba87a6428100e735ba1d041e7aac2 (patch)
tree0b26260efce8da808ad742b0545f41adae2fcb73
parent90da8c8f15db2c82aece6e4085aaf9c116d481f2 (diff)
parentea3c64e6fe432a91938e52fe9529d4fea0961b66 (diff)
downloadppp-813c1e1d6d2ba87a6428100e735ba1d041e7aac2.tar.gz
Merge changes from topic "pppolac"
* changes: pppd: Convert Android.mk to Android.bp pppd: Add rules for building the pppol2tp-android plugin pppd: Fix pppol2tp-android.so build pppd: Enable plugin support in pppd pppd: Add pppol2tp-android plugin pppd: Remove obsolete way of receiving args from mtpd
-rw-r--r--Android.bp15
-rw-r--r--pppd/Android.bp88
-rw-r--r--pppd/Android.mk46
-rw-r--r--pppd/README.pppol2tp33
-rw-r--r--pppd/include/net/ppp_defs.h8
-rw-r--r--pppd/main.c27
-rw-r--r--pppd/pathnames.h16
-rw-r--r--pppd/plugins/pppol2tp-android/pppol2tp-android.c129
8 files changed, 291 insertions, 71 deletions
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..3704241
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,15 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+subdirs = ["pppd"]
diff --git a/pppd/Android.bp b/pppd/Android.bp
new file mode 100644
index 0000000..d995a0d
--- /dev/null
+++ b/pppd/Android.bp
@@ -0,0 +1,88 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_defaults {
+ name: "ppp_defaults",
+ cflags: [
+ "-DCHAPMS=1",
+ "-DMPPE=1",
+ "-DINET6=1",
+ "-DUSE_OPENSSL=1",
+ "-Wno-missing-field-initializers",
+ "-Wno-unused-parameter",
+ "-Werror",
+ "-Wno-pointer-sign",
+ ],
+ local_include_dirs: ["include"],
+}
+
+cc_binary {
+ name: "pppd",
+ defaults: ["ppp_defaults"],
+
+ srcs: [
+ "auth.c",
+ "ccp.c",
+ "chap-md5.c",
+ "chap-new.c",
+ "chap_ms.c",
+ "demand.c",
+ "eap.c",
+ "ecp.c",
+ "eui64.c",
+ "fsm.c",
+ "ipcp.c",
+ "ipv6cp.c",
+ "lcp.c",
+ "magic.c",
+ "main.c",
+ "options.c",
+ "pppcrypt.c",
+ "pppox.c",
+ "session.c",
+ "sys-linux.c",
+ "tty.c",
+ "upap.c",
+ "utils.c",
+ ],
+
+ // options.c:623:21: error: passing 'const char *' to parameter of
+ // type 'char *' discards qualifiers.
+ // [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
+ clang_cflags: ["-Wno-incompatible-pointer-types-discards-qualifiers"],
+
+ shared_libs: [
+ "libdl",
+ "liblog",
+ "libcutils",
+ "libcrypto",
+ ],
+
+ cflags: [
+ "-Wno-empty-body",
+ "-Wno-attributes",
+ "-Wno-sign-compare",
+ "-DPLUGIN",
+ ],
+
+ ldflags: ["-rdynamic"],
+ required: ["pppol2tp-android"],
+}
+
+cc_library_shared {
+ name: "pppol2tp-android",
+ defaults: ["ppp_defaults"],
+ srcs: ["plugins/pppol2tp-android/pppol2tp-android.c"],
+ allow_undefined_symbols: true,
+}
diff --git a/pppd/Android.mk b/pppd/Android.mk
deleted file mode 100644
index 88cfe35..0000000
--- a/pppd/Android.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- auth.c \
- ccp.c \
- chap-md5.c \
- chap-new.c \
- chap_ms.c \
- demand.c \
- eap.c \
- ecp.c \
- eui64.c \
- fsm.c \
- ipcp.c \
- ipv6cp.c \
- lcp.c \
- magic.c \
- main.c \
- options.c \
- pppcrypt.c \
- pppox.c \
- session.c \
- sys-linux.c \
- tty.c \
- upap.c \
- utils.c
-
-# options.c:623:21: error: passing 'const char *' to parameter of type 'char *' discards qualifiers.
-# [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
-LOCAL_CLANG_CFLAGS += -Wno-incompatible-pointer-types-discards-qualifiers
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils liblog libcrypto
-
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/include
-
-LOCAL_CFLAGS := -DCHAPMS=1 -DMPPE=1 -DINET6=1 -DUSE_OPENSSL=1 -Wno-unused-parameter -Wno-empty-body -Wno-missing-field-initializers -Wno-attributes -Wno-sign-compare -Wno-pointer-sign -Werror
-
-# Turn off warnings for now until this is fixed upstream. b/18632512
-LOCAL_CFLAGS += -Wno-unused-variable
-
-LOCAL_MODULE:= pppd
-
-include $(BUILD_EXECUTABLE)
diff --git a/pppd/README.pppol2tp b/pppd/README.pppol2tp
new file mode 100644
index 0000000..e82548a
--- /dev/null
+++ b/pppd/README.pppol2tp
@@ -0,0 +1,33 @@
+PPPoL2TP-Android plugin
+=======================
+
+This PPPoL2TP-Android plugin was written for AOSP project from scratch. It has
+nothing to do with pppol2tp plugin from upstream ppp project [1].
+
+This plugin adds support for upstream kernel L2TP implementation in pppd
+daemon. Only LAC part of L2TP is implemented, as we don't use Android devices
+in LNS mode.
+
+In general case, the execution flow for VPN startup on Android devices is:
+ 1. Run IPSec client (racoon)
+ 2. Run L2TP client (mtpd)
+ 3. mtpd obtains "remote tunnel ID" and "remote session ID" from L2TP server
+ 4. mtpd creates L2TP sockets (see [2] for details):
+ - tunnel management PPPoX socket
+ - session PPPoX data socket
+ 5. mtpd runs pppd, passing arguments for pppol2tp-android plugin
+ 6. pppd dlopen() pppol2tp-android plugin (because it receives corresponding\
+ arguments from mtpd)
+
+Main task of this plugin is to obtain session_fd socket from mtpd and pass it
+back to pppd when .connect() callback is executed. In this respect it's similar
+to old pppox.c implementation. The differences are next:
+ 1. pppol2tp-android also obtains the second socket (for tunnel management)
+ which allows us to handle it properly
+ 2. pppol2tp-android handles the setting of MTU/MRU size (which can be passed
+ to the plugin with pppd parameters) via kernel L2TP implementation
+ 3. pppol2tp-android plugin is actually loaded dynamically with dlopen(),
+ as opposed to pppox.c which is hard-coded into pppd code
+
+[1] https://github.com/paulusmack/ppp
+[2] https://www.kernel.org/doc/Documentation/networking/l2tp.txt
diff --git a/pppd/include/net/ppp_defs.h b/pppd/include/net/ppp_defs.h
index a21afdb..9522290 100644
--- a/pppd/include/net/ppp_defs.h
+++ b/pppd/include/net/ppp_defs.h
@@ -38,6 +38,10 @@
#ifndef _PPP_DEFS_H_
#define _PPP_DEFS_H_
+#if defined(__linux__)
+#include <linux/ppp_defs.h>
+#endif
+
#if defined(PPP_ADDRESS)
#define USING_UAPI
#endif
@@ -131,6 +135,10 @@ typedef u_int32_t ext_accm[8];
* What to do with network protocol (NP) packets.
*/
#if defined(USING_UAPI)
+
+/* For struct ifreq */
+#include <net/if.h>
+
/* This stuff isn't in uapi. TODO: is there a newer pppd that doesn't use this? */
#define ifr__name b.ifr_ifrn.ifrn_name
#define stats_ptr b.ifr_ifru.ifru_data
diff --git a/pppd/main.c b/pppd/main.c
index 5424e42..09f5a53 100644
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -357,39 +357,16 @@ main(argc, argv)
*/
tty_init();
- progname = *argv;
-
#if defined(__ANDROID__)
{
extern void pppox_init();
pppox_init();
privileged = 1;
}
- {
- char *envargs = getenv("envargs");
- if (envargs) {
- int i;
- /* Decode the arguments in-place and count the number of them.
- * They were hex encoded using [A-P] instead of [0-9A-F]. */
- for (argc = 0, i = 0; envargs[i] && envargs[i + 1]; i += 2) {
- char c = ((envargs[i] - 'A') << 4) + (envargs[i + 1] - 'A');
- if (c == 0) {
- ++argc;
- }
- envargs[i / 2 + 1] = c;
- }
- if (argc == 0 || (argv = malloc(sizeof(char *) * argc)) == NULL) {
- fatal("Failed to parse envargs!");
- }
- for (envargs[0] = 0, i = 0; i < argc; ++envargs) {
- if (envargs[0] == 0) {
- argv[i++] = &envargs[1];
- }
- }
- }
- }
#endif
+ progname = *argv;
+
/*
* Parse, in order, the system options file, the user's options file,
* and the command line arguments.
diff --git a/pppd/pathnames.h b/pppd/pathnames.h
index a33f046..ea74736 100644
--- a/pppd/pathnames.h
+++ b/pppd/pathnames.h
@@ -56,10 +56,26 @@
#endif /* __STDC__ */
#ifdef PLUGIN
+#ifdef __ANDROID__
+
+/*
+ * In Android we can't load plugins from /system/lib{64}/pppd/, because
+ * Bionic loader only allows us to dlopen() libraries from /system/lib{64} root
+ * directory (as specified in ld.config.txt, see "default" linker namespace).
+ */
+#ifdef __LP64__
+#define _PATH_PLUGIN "/system/lib64"
+#else /* __LP64__ */
+#define _PATH_PLUGIN "/system/lib"
+#endif /* __LP64__ */
+
+#else /* __ANDROID__ */
+
#ifdef __STDC__
#define _PATH_PLUGIN DESTDIR "/lib/pppd/" VERSION
#else /* __STDC__ */
#define _PATH_PLUGIN "/usr/lib/pppd"
#endif /* __STDC__ */
+#endif /* __ANDROID__ */
#endif /* PLUGIN */
diff --git a/pppd/plugins/pppol2tp-android/pppol2tp-android.c b/pppd/plugins/pppol2tp-android/pppol2tp-android.c
new file mode 100644
index 0000000..6a984de
--- /dev/null
+++ b/pppd/plugins/pppol2tp-android/pppol2tp-android.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "pppd.h"
+#include "fsm.h"
+#include "lcp.h"
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/if_ppp.h>
+
+char pppd_version[] = VERSION;
+
+static struct channel pppol2tp_channel;
+
+/* Options variables */
+static int session_fd = -1;
+static int tunnel_fd = -1;
+static int session_id = 0;
+static int tunnel_id = 0;
+
+static int pppol2tp_set_session_fd(char **argv);
+
+static option_t pppol2tp_options[] = {
+ { "session_fd", o_special, pppol2tp_set_session_fd,
+ "Session PPPoX data socket", OPT_DEVNAM },
+ { "tunnel_fd", o_int, &tunnel_fd,
+ "Tunnel management PPPoX socket", OPT_PRIO },
+ { "session_id", o_int, &session_id, "Session ID", OPT_PRIO },
+ { "tunnel_id", o_int, &tunnel_id, "Tunnel ID", OPT_PRIO },
+ { NULL }
+};
+
+static int pppol2tp_set_session_fd(char **argv)
+{
+ if (!int_option(*argv, &session_fd))
+ return 0;
+
+ info("Using PPPoL2TP (socket = %d)", session_fd);
+ the_channel = &pppol2tp_channel;
+ return 1;
+}
+
+/**
+ * Set the MRU on the PPP network interface.
+ *
+ * @param mru New MRU value
+ *
+ * @note netif_set_mru() is missing in sys-linux.c, so implement it manually
+ * @note See net/l2tp/l2tp_ppp.c:pppol2tp_session_ioctl() in kernel for details
+ */
+static void pppol2tp_set_mru(int mru)
+{
+ int res;
+
+ if (ifunit < 0)
+ return;
+
+ res = ioctl(session_fd, PPPIOCSMRU, (caddr_t)&mru);
+ if (res < 0)
+ error("ioctl(PPPIOCSMRU): %m (line %d)", __LINE__);
+}
+
+/* Set the transmit-side PPP parameters of the channel */
+static void pppol2tp_send_config(int mtu, u_int32_t accm, int pcomp, int accomp)
+{
+ int new_mtu = lcp_allowoptions[0].mru; /* "mtu" pppd option */
+
+ if (new_mtu <= PPP_MAXMTU && new_mtu >= PPP_MINMTU)
+ netif_set_mtu(ifunit, new_mtu);
+}
+
+/* Set the receive-side PPP parameters of the channel */
+static void pppol2tp_recv_config(int mru, u_int32_t accm, int pcomp, int accomp)
+{
+ int new_mru = lcp_wantoptions[0].mru; /* "mru" pppd option */
+
+ if (new_mru <= PPP_MAXMRU && new_mru >= PPP_MINMRU)
+ pppol2tp_set_mru(new_mru);
+}
+
+static int pppol2tp_connect(void)
+{
+ return session_fd;
+}
+
+static void pppol2tp_disconnect(void)
+{
+ if (session_fd != -1) {
+ close(session_fd);
+ session_fd = -1;
+ }
+
+ if (tunnel_fd != -1) {
+ close(tunnel_fd);
+ tunnel_fd = -1;
+ }
+}
+
+void plugin_init(void)
+{
+ add_options(pppol2tp_options);
+}
+
+static struct channel pppol2tp_channel = {
+ .options = pppol2tp_options,
+ .process_extra_options = NULL,
+ .check_options = NULL,
+ .connect = pppol2tp_connect,
+ .disconnect = pppol2tp_disconnect,
+ .establish_ppp = generic_establish_ppp,
+ .disestablish_ppp = generic_disestablish_ppp,
+ .send_config = pppol2tp_send_config,
+ .recv_config = pppol2tp_recv_config,
+ .cleanup = NULL,
+ .close = NULL,
+};