mtpd: Use PPTP implementation from upstream kernel

Add upstream kernel implementation of PPTP protocol. This code uses
pppopptp-android plugin, which was added to pppd project.

This patch changes the behavior of PPTP part of mtpd tool in a next way:
 - check if upstream kernel implementation of PPTP is enabled (in
   check_pptp() function)
    - if yes, use it:
      - create PX_PROTO_PPTP socket (in create_pppox_pptp() function)
      - and start pppd with pppopptp-android plugin (in
        start_pppd_pptp() function)
    - if no, fall back to use Android kernel implementation of PPTP
      - create PX_PROTO_OPNS socket (in create_pppox_opns() function)
      - and start pppd with pppox module (in start_pppd() function)

mtpd still handles PPTP control packets, while pppd handles PPP packets,
and kernel PPTP driver handles data packets.

After this patch, old implementation (PX_PROTO_OPNS) can be dropped from
Android kernel. After some transition time we can keep only PPTP support
in mtpd and drop OPNS support for good.

In order to use this PPTP implementation, next kernel option should be
enabled:

    CONFIG_PPTP=y

For more details see: [1].

[1] https://wiki.linaro.org/LMG/Kernel/PPP

Change-Id: Ia6d54ffe7748bd87424ea74250164b73eb4b6000
Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
diff --git a/mtpd.c b/mtpd.c
index 53ea362..ac724ac 100644
--- a/mtpd.c
+++ b/mtpd.c
@@ -418,3 +418,56 @@
     close(session_fd);
     close(tunnel_fd);
 }
+
+/**
+ * Start pppd daemon with pppopptp-android plugin.
+ *
+ * @param pptp_fd PPTP socket file descriptor
+ */
+void start_pppd_pptp(int pptp_fd)
+{
+    if (pppd_pid) {
+        log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid);
+        goto ret;
+    }
+
+    log_print(INFO, "Starting pppd (pptp_fd = %d)", pptp_fd);
+
+    pppd_pid = fork();
+    if (pppd_pid < 0) {
+        log_print(FATAL, "Fork() %s", strerror(errno));
+        exit(SYSTEM_ERROR);
+    }
+
+    if (!pppd_pid) {
+        char pptp_fd_str[FD_MAX_LEN + 1];
+
+        snprintf(pptp_fd_str, FD_MAX_LEN + 1, "%d", pptp_fd);
+
+        const char *pptp_args[] = {
+            "pppd",
+            "nodetach",
+            "plugin",
+            "pppopptp-android.so",
+            "pptp_socket",
+            pptp_fd_str,
+        };
+        const size_t args_len = ARRAY_SIZE(pptp_args) + pppd_argc + 1;
+        char *args[args_len];
+
+        /* Populate args[] from pptp_args[] and pppd_argv[] */
+        memcpy(args, pptp_args, sizeof(pptp_args));
+        memcpy(args + ARRAY_SIZE(pptp_args), pppd_argv,
+                sizeof(char *) * pppd_argc);
+        args[args_len - 1] = NULL;
+
+        execvp("pppd", args);
+        log_print(FATAL, "Exec() %s", strerror(errno));
+        exit(SYSTEM_ERROR); /* Pretending a fatal error in pppd. */
+    }
+
+    log_print(INFO, "Pppd started (pid = %d)", pppd_pid);
+
+ret:
+    close(pptp_fd);
+}