Merge "Remove mtpd" into main am: 98c77a5a58 am: 05b547a953 am: 1aaa0adb42

Original change: https://android-review.googlesource.com/c/platform/external/mtpd/+/2825795

Change-Id: Ic4123c1c77835030990fa843f6a7df832b0bf0b1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 9efa325..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) 2016 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.
-
-package {
-    default_applicable_licenses: ["external_mtpd_license"],
-}
-
-// Added automatically by a large-scale-change
-// See: http://go/android-license-faq
-license {
-    name: "external_mtpd_license",
-    visibility: [":__subpackages__"],
-    license_kinds: [
-        "SPDX-license-identifier-Apache-2.0",
-    ],
-    license_text: [
-        "NOTICE",
-    ],
-}
-
-cc_binary {
-    name: "mtpd",
-    srcs: [
-        "mtpd.c",
-        "l2tp.c",
-        "pptp.c"
-    ],
-    shared_libs: [
-        "libcrypto",
-        "libcutils",
-        "liblog",
-        "libnetd_client",
-    ],
-    cflags: [
-        "-DANDROID_CHANGES",
-        "-Wall",
-        "-Werror",
-    ],
-    init_rc: ["mtpd.rc"],
-}
diff --git a/METADATA b/METADATA
deleted file mode 100644
index d97975c..0000000
--- a/METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-third_party {
-  license_type: NOTICE
-}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index 64aaa8d..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2009, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/OWNERS b/OWNERS
deleted file mode 100644
index c24680e..0000000
--- a/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-set noparent
-file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
diff --git a/l2tp.c b/l2tp.c
deleted file mode 100644
index ae6088d..0000000
--- a/l2tp.c
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-/*
- * Implementation of L2TP Access Concentrator (RFC 2661). The following code
- * only handles control packets. Data packets are handled by kernel driver:
- *  - PX_PROTO_OL2TP (upstream impl.), if it's enabled in kernel
- *  - or PX_PROTO_OLAC (Android impl.), if upstream implementation is not
- *    available / not enabled. It will be removed in new Android kernels.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <linux/netdevice.h>
-#include <linux/if_pppox.h>
-#include <linux/types.h>
-#include <openssl/md5.h>
-
-#include "mtpd.h"
-
-/* To avoid unnecessary endianness conversions, tunnels, sessions, attributes,
- * and values are all accessed in network order. */
-
-/* 0 is reserved. We put ACK here just for convenience. */
-enum l2tp_message {
-    ACK = 0,
-    SCCRQ = 1,
-    SCCRP = 2,
-    SCCCN = 3,
-    STOPCCN = 4,
-    HELLO = 6,
-    OCRQ = 7,
-    OCRP = 8,
-    OCCN = 9,
-    ICRQ = 10,
-    ICRP = 11,
-    ICCN = 12,
-    CDN = 14,
-    WEN = 15,
-    SLI = 16,
-    MESSAGE_MAX = 16,
-};
-
-static char *messages[] = {
-    "ACK", "SCCRQ", "SCCRP", "SCCCN", "STOPCCN", NULL, "HELLO", "OCRQ",
-    "OCRP", "OCCN", "ICRQ", "ICRP", "ICCN", NULL, "CDN", "WEN", "SLI",
-};
-
-/* This is incomplete. Only those we used are listed here. */
-#define RESULT_CODE             htons(1)
-#define PROTOCOL_VERSION        htons(2)
-#define FRAMING_CAPABILITIES    htons(3)
-#define HOST_NAME               htons(7)
-#define ASSIGNED_TUNNEL         htons(9)
-#define WINDOW_SIZE             htons(10)
-#define CHALLENGE               htons(11)
-#define CHALLENGE_RESPONSE      htons(13)
-#define ASSIGNED_SESSION        htons(14)
-#define CALL_SERIAL_NUMBER      htons(15)
-#define FRAMING_TYPE            htons(19)
-#define CONNECT_SPEED           htons(24)
-#define RANDOM_VECTOR           htons(36)
-
-#define MESSAGE_FLAG            0xC802
-#define MESSAGE_MASK            0xCB0F
-#define ATTRIBUTE_FLAG(length)  (0x8006 + (length))
-#define ATTRIBUTE_LENGTH(flag)  (0x03FF & (flag))
-#define ATTRIBUTE_HIDDEN(flag)  (0x4000 & (flag))
-
-#define ACK_SIZE                12
-#define MESSAGE_HEADER_SIZE     20
-#define ATTRIBUTE_HEADER_SIZE   6
-#define MAX_ATTRIBUTE_SIZE      1024
-
-static __be16 local_tunnel;
-static __be16 local_session;
-static uint16_t local_sequence;
-static __be16 remote_tunnel;
-static __be16 remote_session;
-static uint16_t remote_sequence;
-
-static uint16_t state;
-static int acknowledged;
-
-#define RANDOM_DEVICE   "/dev/urandom"
-#define CHALLENGE_SIZE  32
-
-static char *secret;
-static int secret_length;
-static uint8_t challenge[CHALLENGE_SIZE];
-
-/* According to RFC 2661 page 46, an exponential backoff strategy is required
- * for retransmission. However, it might waste too much time waiting for IPsec
- * negotiation. Here we use the same interval to keep things simple. */
-#define TIMEOUT_INTERVAL 2000
-
-#define MAX_PACKET_LENGTH 2048
-
-static struct packet {
-    int message;
-    int length;
-    uint8_t buffer[MAX_PACKET_LENGTH] __attribute__((aligned(4)));
-} incoming, outgoing;
-
-struct attribute {
-    uint16_t flag;
-    uint16_t vendor;
-    uint16_t type;
-    uint8_t value[1];
-} __attribute__((packed));
-
-static void set_message(uint16_t session, uint16_t message)
-{
-    uint16_t *p = (uint16_t *)outgoing.buffer;
-    p[0] = htons(MESSAGE_FLAG);
-    /* p[1] will be filled in send_packet(). */
-    p[2] = remote_tunnel;
-    p[3] = session;
-    p[4] = htons(local_sequence);
-    p[5] = htons(remote_sequence);
-    p[6] = htons(ATTRIBUTE_FLAG(2));
-    p[7] = 0;
-    p[8] = 0;
-    p[9] = htons(message);
-    outgoing.message = message;
-    outgoing.length = MESSAGE_HEADER_SIZE;
-    ++local_sequence;
-}
-
-static void add_attribute_raw(uint16_t type, void *value, int size)
-{
-    struct attribute *p = (struct attribute *)&outgoing.buffer[outgoing.length];
-    p->flag = htons(ATTRIBUTE_FLAG(size));
-    p->vendor = 0;
-    p->type = type;
-    memcpy(&p->value, value, size);
-    outgoing.length += ATTRIBUTE_HEADER_SIZE + size;
-}
-
-static void add_attribute_u16(uint16_t attribute, uint16_t value)
-{
-    add_attribute_raw(attribute, &value, sizeof(uint16_t));
-}
-
-static void add_attribute_u32(uint16_t attribute, uint32_t value)
-{
-    add_attribute_raw(attribute, &value, sizeof(uint32_t));
-}
-
-static void send_packet()
-{
-    uint16_t *p = (uint16_t *)outgoing.buffer;
-    p[1] = htons(outgoing.length);
-    send(the_socket, outgoing.buffer, outgoing.length, 0);
-    acknowledged = 0;
-}
-
-static void send_ack()
-{
-    uint16_t buffer[6] = {
-        htons(MESSAGE_FLAG), htons(ACK_SIZE), remote_tunnel, 0,
-        htons(local_sequence), htons(remote_sequence),
-    };
-    send(the_socket, buffer, ACK_SIZE, 0);
-}
-
-static int recv_packet(uint16_t *session)
-{
-    uint16_t *p = (uint16_t *)incoming.buffer;
-
-    incoming.length = recv(the_socket, incoming.buffer, MAX_PACKET_LENGTH, 0);
-    if (incoming.length == -1) {
-        if (errno == EINTR) {
-            return 0;
-        }
-        log_print(FATAL, "Recv() %s", strerror(errno));
-        exit(NETWORK_ERROR);
-    }
-
-    /* We only handle packets in our tunnel. */
-    if ((incoming.length != ACK_SIZE && incoming.length < MESSAGE_HEADER_SIZE)
-            || (p[0] & htons(MESSAGE_MASK)) != htons(MESSAGE_FLAG) ||
-            ntohs(p[1]) != incoming.length || p[2] != local_tunnel) {
-        return 0;
-    }
-
-    if (incoming.length == ACK_SIZE) {
-        incoming.message = ACK;
-    } else if (p[6] == htons(ATTRIBUTE_FLAG(2)) && !p[7] && !p[8]) {
-        incoming.message = ntohs(p[9]);
-    } else {
-        return 0;
-    }
-
-    /* Check if the packet is duplicated and send ACK if necessary. */
-    if ((uint16_t)(ntohs(p[4]) - remote_sequence) > 32767) {
-        if (incoming.message != ACK) {
-            send_ack();
-        }
-        return 0;
-    }
-
-    if (ntohs(p[5]) == local_sequence) {
-        acknowledged = 1;
-    }
-
-    /* Our sending and receiving window sizes are both 1. Thus we only handle
-     * this packet if it is their next one and they received our last one. */
-    if (ntohs(p[4]) != remote_sequence || !acknowledged) {
-        return 0;
-    }
-    *session = p[3];
-    if (incoming.message != ACK) {
-        ++remote_sequence;
-    }
-    return 1;
-}
-
-static int get_attribute_raw(uint16_t type, void *value, int size)
-{
-    int offset = MESSAGE_HEADER_SIZE;
-    uint8_t *vector = NULL;
-    int vector_length = 0;
-
-    while (incoming.length >= offset + ATTRIBUTE_HEADER_SIZE) {
-        struct attribute *p = (struct attribute *)&incoming.buffer[offset];
-        uint16_t flag = ntohs(p->flag);
-        int length = ATTRIBUTE_LENGTH(flag);
-
-        offset += length;
-        length -= ATTRIBUTE_HEADER_SIZE;
-        if (length < 0 || offset > incoming.length) {
-            break;
-        }
-        if (p->vendor) {
-            continue;
-        }
-        if (p->type != type) {
-            if (p->type == RANDOM_VECTOR && !ATTRIBUTE_HIDDEN(flag)) {
-                vector = p->value;
-                vector_length = length;
-            }
-            continue;
-        }
-
-        if (!ATTRIBUTE_HIDDEN(flag)) {
-            if (size > length) {
-                size = length;
-            }
-            memcpy(value, p->value, size);
-            return size;
-        }
-
-        if (!secret || !vector || length < 2) {
-            return 0;
-        } else {
-            uint8_t buffer[MAX_ATTRIBUTE_SIZE];
-            uint8_t hash[MD5_DIGEST_LENGTH];
-            MD5_CTX ctx;
-            int i;
-
-            MD5_Init(&ctx);
-            MD5_Update(&ctx, &type, sizeof(uint16_t));
-            MD5_Update(&ctx, secret, secret_length);
-            MD5_Update(&ctx, vector, vector_length);
-            MD5_Final(hash, &ctx);
-
-            for (i = 0; i < length; ++i) {
-                int j = i % MD5_DIGEST_LENGTH;
-                if (i && !j) {
-                    MD5_Init(&ctx);
-                    MD5_Update(&ctx, secret, secret_length);
-                    MD5_Update(&ctx, &p->value[i - MD5_DIGEST_LENGTH],
-                        MD5_DIGEST_LENGTH);
-                    MD5_Final(hash, &ctx);
-                }
-                buffer[i] = p->value[i] ^ hash[j];
-            }
-
-            length = buffer[0] << 8 | buffer[1];
-            if (length > i - 2) {
-                return 0;
-            }
-            if (size > length) {
-                size = length;
-            }
-            memcpy(value, &buffer[2], size);
-            return size;
-        }
-    }
-    return 0;
-}
-
-static int get_attribute_u16(uint16_t type, uint16_t *value)
-{
-    return get_attribute_raw(type, value, sizeof(uint16_t)) == sizeof(uint16_t);
-}
-
-static int l2tp_connect(char **arguments)
-{
-    create_socket(AF_INET, SOCK_DGRAM, arguments[0], arguments[1]);
-
-    while (!local_tunnel) {
-        local_tunnel = random();
-    }
-
-    log_print(DEBUG, "Sending SCCRQ (local_tunnel = %u)",
-              (unsigned)ntohs(local_tunnel));
-    state = SCCRQ;
-    set_message(0, SCCRQ);
-    add_attribute_u16(PROTOCOL_VERSION, htons(0x0100));
-    add_attribute_raw(HOST_NAME, "anonymous", 9);
-    add_attribute_u32(FRAMING_CAPABILITIES, htonl(3));
-    add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel);
-    add_attribute_u16(WINDOW_SIZE, htons(1));
-
-    if (arguments[2][0]) {
-        int fd = open(RANDOM_DEVICE, O_RDONLY);
-        if (fd == -1 || read(fd, challenge, CHALLENGE_SIZE) != CHALLENGE_SIZE) {
-            log_print(FATAL, "Cannot read %s", RANDOM_DEVICE);
-            exit(SYSTEM_ERROR);
-        }
-        close(fd);
-
-        add_attribute_raw(CHALLENGE, challenge, CHALLENGE_SIZE);
-        secret = arguments[2];
-        secret_length = strlen(arguments[2]);
-    }
-
-    send_packet();
-    return TIMEOUT_INTERVAL;
-}
-
-/**
- * Check if upstream kernel implementation of L2TP should be used.
- *
- * @return true If upstream L2TP should be used, which is the case if
- *              the obsolete OLAC feature is not available.
- */
-static bool check_ol2tp(void)
-{
-    int fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OLAC);
-
-    if (fd < 0) {
-        return true;
-    } else {
-        close(fd);
-        return false;
-    }
-}
-
-/**
- * Create OLAC session.
- *
- * @deprecated It will be removed soon in favor of upstream OL2TP.
- *
- * @return PPPoX socket file descriptor
- */
-static int create_pppox_olac(void)
-{
-    int pppox;
-
-    log_print(WARNING, "Using deprecated OLAC protocol. "
-                       "Its support will be removed soon. "
-                       "Please enable OL2TP support in your kernel");
-
-    log_print(INFO, "Creating PPPoX socket");
-    pppox = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OLAC);
-
-    if (pppox == -1) {
-        log_print(FATAL, "Socket() %s", strerror(errno));
-        exit(SYSTEM_ERROR);
-    } else {
-        struct sockaddr_pppolac address = {
-            .sa_family = AF_PPPOX,
-            .sa_protocol = PX_PROTO_OLAC,
-            .udp_socket = the_socket,
-            .local = {.tunnel = local_tunnel, .session = local_session},
-            .remote = {.tunnel = remote_tunnel, .session = remote_session},
-        };
-        if (connect(pppox, (struct sockaddr *)&address, sizeof(address))) {
-            log_print(FATAL, "Connect() %s", strerror(errno));
-            exit(SYSTEM_ERROR);
-        }
-    }
-    return pppox;
-}
-
-/**
- * Create OL2TP tunnel and session.
- *
- * @param[out] tfd Will contain tunnel socket file descriptor
- * @param[out] sfd Will contain session socket file descriptor
- */
-static void create_pppox_ol2tp(int *tfd, int *sfd)
-{
-    int tunnel_fd;
-    int session_fd;
-    struct sockaddr_pppol2tp tunnel_sa;
-    struct sockaddr_pppol2tp session_sa;
-
-    log_print(INFO, "Creating PPPoX tunnel socket...");
-    tunnel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
-    if (tunnel_fd < 0) {
-        log_print(FATAL, "Tunnel socket(): %s", strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-
-    memset(&tunnel_sa, 0, sizeof(tunnel_sa));
-    tunnel_sa.sa_family = AF_PPPOX;
-    tunnel_sa.sa_protocol = PX_PROTO_OL2TP;
-    tunnel_sa.pppol2tp.fd = the_socket; /* UDP socket */
-    tunnel_sa.pppol2tp.s_tunnel = ntohs(local_tunnel);
-    tunnel_sa.pppol2tp.s_session = 0;   /* special case: mgmt socket */
-    tunnel_sa.pppol2tp.d_tunnel = ntohs(remote_tunnel);
-    tunnel_sa.pppol2tp.d_session = 0;   /* special case: mgmt socket */
-
-    log_print(INFO, "Connecting to tunnel socket...");
-    if (connect(tunnel_fd, (struct sockaddr *)&tunnel_sa,
-                sizeof(tunnel_sa))) {
-        log_print(FATAL, "Tunnel connect(): %s", strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-
-    log_print(INFO, "Creating PPPoX session socket...");
-    session_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
-    if (session_fd < 0) {
-        log_print(FATAL, "Session socket(): %s", strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-
-    memset(&session_sa, 0, sizeof(session_sa));
-    session_sa.sa_family = AF_PPPOX;
-    session_sa.sa_protocol = PX_PROTO_OL2TP;
-    session_sa.pppol2tp.fd = the_socket;
-    session_sa.pppol2tp.s_tunnel = ntohs(local_tunnel);
-    session_sa.pppol2tp.s_session = ntohs(local_session);
-    session_sa.pppol2tp.d_tunnel = ntohs(remote_tunnel);
-    session_sa.pppol2tp.d_session = ntohs(remote_session);
-
-    log_print(INFO, "Connecting to session socket...");
-    if (connect(session_fd, (struct sockaddr *)&session_sa,
-                sizeof(session_sa))) {
-        log_print(FATAL, "Session connect(): %s", strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-
-    *tfd = tunnel_fd;
-    *sfd = session_fd;
-}
-
-static uint8_t *compute_response(uint8_t type, void *challenge, int size)
-{
-    static uint8_t response[MD5_DIGEST_LENGTH];
-    MD5_CTX ctx;
-    MD5_Init(&ctx);
-    MD5_Update(&ctx, &type, sizeof(uint8_t));
-    MD5_Update(&ctx, secret, secret_length);
-    MD5_Update(&ctx, challenge, size);
-    MD5_Final(response, &ctx);
-    return response;
-}
-
-static bool verify_challenge()
-{
-    if (secret) {
-        uint8_t response[MD5_DIGEST_LENGTH];
-        if (get_attribute_raw(CHALLENGE_RESPONSE, response, MD5_DIGEST_LENGTH)
-                != MD5_DIGEST_LENGTH) {
-            return false;
-        }
-        return !memcmp(compute_response(SCCRP, challenge, CHALLENGE_SIZE),
-                response, MD5_DIGEST_LENGTH);
-    }
-    return true;
-}
-
-static void answer_challenge()
-{
-    if (secret) {
-        uint8_t challenge[MAX_ATTRIBUTE_SIZE];
-        int size = get_attribute_raw(CHALLENGE, challenge, MAX_ATTRIBUTE_SIZE);
-        if (size > 0) {
-            uint8_t *response = compute_response(SCCCN, challenge, size);
-            add_attribute_raw(CHALLENGE_RESPONSE, response, MD5_DIGEST_LENGTH);
-        }
-    }
-}
-
-static int l2tp_process()
-{
-    uint16_t sequence = local_sequence;
-    __be16 tunnel = 0;
-    __be16 session = 0;
-
-    if (!recv_packet(&session)) {
-        return acknowledged ? 0 : TIMEOUT_INTERVAL;
-    }
-
-    /* Here is the fun part. We always try to protect our tunnel and session
-     * from being closed even if we received unexpected messages. */
-    switch(incoming.message) {
-        case SCCRP:
-            if (state == SCCRQ) {
-                if (get_attribute_u16(ASSIGNED_TUNNEL, &tunnel) && tunnel &&
-                        verify_challenge()) {
-                    remote_tunnel = tunnel;
-                    log_print(DEBUG, "Received SCCRP (remote_tunnel = %u) -> "
-                            "Sending SCCCN", (unsigned)ntohs(remote_tunnel));
-                    state = SCCCN;
-                    set_message(0, SCCCN);
-                    answer_challenge();
-                    break;
-                }
-                log_print(DEBUG, "Received SCCRP without %s", tunnel ?
-                        "valid challenge response" : "assigned tunnel");
-                log_print(ERROR, "Protocol error");
-                return tunnel ? -CHALLENGE_FAILED : -PROTOCOL_ERROR;
-            }
-            break;
-
-        case ICRP:
-            if (state == ICRQ && session == local_session) {
-                if (get_attribute_u16(ASSIGNED_SESSION, &session) && session) {
-                    remote_session = session;
-                    log_print(DEBUG, "Received ICRP (remote_session = %u) -> "
-                            "Sending ICCN", (unsigned)ntohs(remote_session));
-                    state = ICCN;
-                    set_message(remote_session, ICCN);
-                    add_attribute_u32(CONNECT_SPEED, htonl(100000000));
-                    add_attribute_u32(FRAMING_TYPE, htonl(3));
-                    break;
-                }
-                log_print(DEBUG, "Received ICRP without assigned session");
-                log_print(ERROR, "Protocol error");
-                return -PROTOCOL_ERROR;
-            }
-            break;
-
-        case STOPCCN:
-            log_print(DEBUG, "Received STOPCCN");
-            log_print(INFO, "Remote server hung up");
-            state = STOPCCN;
-            return -REMOTE_REQUESTED;
-
-        case CDN:
-            if (session && session == local_session) {
-                log_print(DEBUG, "Received CDN (local_session = %u)",
-                        (unsigned)ntohs(local_session));
-                log_print(INFO, "Remote server hung up");
-                return -REMOTE_REQUESTED;
-            }
-            break;
-
-        case ACK:
-        case HELLO:
-        case WEN:
-        case SLI:
-            /* These are harmless, so we just treat them in the same way. */
-            if (state == SCCCN) {
-                while (!local_session) {
-                    local_session = random();
-                }
-                log_print(DEBUG, "Received %s -> Sending ICRQ (local_session = "
-                        "%u)", messages[incoming.message],
-                        (unsigned)ntohs(local_session));
-                log_print(INFO, "Tunnel established");
-                state = ICRQ;
-                set_message(0, ICRQ);
-                add_attribute_u16(ASSIGNED_SESSION, local_session);
-                add_attribute_u32(CALL_SERIAL_NUMBER, random());
-                break;
-            }
-
-            if (incoming.message == ACK) {
-                log_print(DEBUG, "Received ACK");
-            } else {
-                log_print(DEBUG, "Received %s -> Sending ACK",
-                          messages[incoming.message]);
-                send_ack();
-            }
-
-            if (state == ICCN) {
-                log_print(INFO, "Session established");
-                state = ACK;
-
-                if (check_ol2tp()) {
-                    int tunnel_fd, session_fd;
-
-                    create_pppox_ol2tp(&tunnel_fd, &session_fd);
-                    start_pppd_ol2tp(tunnel_fd, session_fd,
-                                     ntohs(remote_tunnel),
-                                     ntohs(remote_session));
-                } else {
-                    start_pppd(create_pppox_olac());
-                }
-            }
-            return 0;
-
-        case ICRQ:
-        case OCRQ:
-            /* Since we run pppd as a client, it does not makes sense to
-             * accept ICRQ or OCRQ. Always send CDN with a proper error. */
-            if (get_attribute_u16(ASSIGNED_SESSION, &session) && session) {
-                log_print(DEBUG, "Received %s (remote_session = %u) -> "
-                        "Sending CDN", messages[incoming.message],
-                        (unsigned)ntohs(session));
-                set_message(session, CDN);
-                add_attribute_u32(RESULT_CODE, htonl(0x00020006));
-                add_attribute_u16(ASSIGNED_SESSION, 0);
-            }
-            break;
-    }
-
-    if (sequence != local_sequence) {
-        send_packet();
-        return TIMEOUT_INTERVAL;
-    }
-
-    /* We reach here if we got an unexpected message. Log it and send ACK. */
-    if (incoming.message > MESSAGE_MAX || !messages[incoming.message]) {
-        log_print(DEBUG, "Received UNKNOWN %d -> Sending ACK anyway",
-                incoming.message);
-    } else {
-        log_print(DEBUG, "Received UNEXPECTED %s -> Sending ACK anyway",
-                messages[incoming.message]);
-    }
-    send_ack();
-    return 0;
-}
-
-static int l2tp_timeout()
-{
-    if (acknowledged) {
-        return 0;
-    }
-    log_print(DEBUG, "Timeout -> Sending %s", messages[outgoing.message]);
-    send(the_socket, outgoing.buffer, outgoing.length, 0);
-    return TIMEOUT_INTERVAL;
-}
-
-static void l2tp_shutdown()
-{
-    if (state != STOPCCN) {
-        log_print(DEBUG, "Sending STOPCCN");
-        set_message(0, STOPCCN);
-        add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel);
-        add_attribute_u16(RESULT_CODE, htons(6));
-        send_packet();
-    }
-}
-
-struct protocol l2tp = {
-    .name = "l2tp",
-    .arguments = 3,
-    .usage = "<server> <port> <secret>",
-    .connect = l2tp_connect,
-    .process = l2tp_process,
-    .timeout = l2tp_timeout,
-    .shutdown = l2tp_shutdown,
-};
diff --git a/mtpd.c b/mtpd.c
deleted file mode 100644
index ac724ac..0000000
--- a/mtpd.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (C) 2009 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 <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <sys/wait.h>
-#include <netdb.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-#include <limits.h>
-
-#ifdef ANDROID_CHANGES
-#include <android/log.h>
-#include <cutils/sockets.h>
-#endif
-
-#include "mtpd.h"
-#include "NetdClient.h"
-
-#define ARRAY_SIZE(a)           (sizeof(a) / sizeof(a[0]))
-/* Characters count in string with max value of unsigned type t */
-#define TYPE_STRLEN_U(t)        ((((sizeof(t) * CHAR_BIT) * 1233) >> 12) + 1)
-/* Length of string with max file descriptor value */
-#define FD_MAX_LEN              TYPE_STRLEN_U(int)
-
-int the_socket = -1;
-
-extern struct protocol l2tp;
-extern struct protocol pptp;
-static struct protocol *protocols[] = {&l2tp, &pptp, NULL};
-static struct protocol *the_protocol;
-
-static char *interface;
-static int pppd_argc;
-static char **pppd_argv;
-static pid_t pppd_pid;
-
-/* We redirect signals to a pipe in order to prevent race conditions. */
-static int signals[2];
-
-static void interrupt(int signal)
-{
-    write(signals[1], &signal, sizeof(int));
-}
-
-static int initialize(int argc, char **argv)
-{
-    int i;
-
-    for (i = 0; protocols[i]; ++i) {
-        struct protocol *p = protocols[i];
-        if (argc - 3 >= p->arguments && !strcmp(argv[2], p->name)) {
-            log_print(INFO, "Using protocol %s", p->name);
-            the_protocol = p;
-            break;
-        }
-    }
-
-    if (!the_protocol) {
-        printf("Usages:\n");
-        for (i = 0; protocols[i]; ++i) {
-            struct protocol *p = protocols[i];
-            printf("  %s interface %s %s pppd-arguments\n",
-                    argv[0], p->name, p->usage);
-        }
-        exit(0);
-    }
-
-    interface = argv[1];
-    pppd_argc = argc - 3 - the_protocol->arguments;
-    pppd_argv = &argv[3 + the_protocol->arguments];
-    return the_protocol->connect(&argv[3]);
-}
-
-static void stop_pppd()
-{
-    if (pppd_pid) {
-        int status;
-        log_print(INFO, "Sending signal to pppd (pid = %d)", pppd_pid);
-        kill(pppd_pid, SIGTERM);
-        waitpid(pppd_pid, &status, 0);
-        pppd_pid = 0;
-    }
-}
-
-#ifdef ANDROID_CHANGES
-
-static int android_get_control_and_arguments(int *argc, char ***argv)
-{
-    static char *args[32];
-    int control;
-    int i;
-
-    if ((i = android_get_control_socket("mtpd")) == -1) {
-        return -1;
-    }
-    log_print(DEBUG, "Waiting for control socket");
-    if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
-        log_print(FATAL, "Cannot get control socket");
-        exit(SYSTEM_ERROR);
-    }
-    close(i);
-    fcntl(control, F_SETFD, FD_CLOEXEC);
-
-    args[0] = (*argv)[0];
-    for (i = 1; i < 32; ++i) {
-        unsigned char bytes[2];
-        if (recv(control, &bytes[0], 1, 0) != 1 ||
-                recv(control, &bytes[1], 1, 0) != 1) {
-            log_print(FATAL, "Cannot get argument length");
-            exit(SYSTEM_ERROR);
-        } else {
-            int length = bytes[0] << 8 | bytes[1];
-            int offset = 0;
-
-            if (length == 0xFFFF) {
-                break;
-            }
-            args[i] = malloc(length + 1);
-            while (offset < length) {
-                int n = recv(control, &args[i][offset], length - offset, 0);
-                if (n > 0) {
-                    offset += n;
-                } else {
-                    log_print(FATAL, "Cannot get argument value");
-                    exit(SYSTEM_ERROR);
-                }
-            }
-            args[i][length] = 0;
-        }
-    }
-    log_print(DEBUG, "Received %d arguments", i - 1);
-
-    *argc = i;
-    *argv = args;
-    return control;
-}
-
-#endif
-
-int main(int argc, char **argv)
-{
-    struct pollfd pollfds[3];
-    int control = -1;
-    int timeout;
-    int status;
-
-#ifdef ANDROID_CHANGES
-    control = android_get_control_and_arguments(&argc, &argv);
-    shutdown(control, SHUT_WR);
-#endif
-
-    srandom(time(NULL));
-
-    if (pipe(signals) == -1) {
-        log_print(FATAL, "Pipe() %s", strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-    fcntl(signals[0], F_SETFD, FD_CLOEXEC);
-    fcntl(signals[1], F_SETFD, FD_CLOEXEC);
-
-    timeout = initialize(argc, argv);
-
-    signal(SIGHUP, interrupt);
-    signal(SIGINT, interrupt);
-    signal(SIGTERM, interrupt);
-    signal(SIGCHLD, interrupt);
-    signal(SIGPIPE, SIG_IGN);
-    atexit(stop_pppd);
-
-    pollfds[0].fd = the_socket;
-    pollfds[0].events = POLLIN;
-    pollfds[1].fd = signals[0];
-    pollfds[1].events = POLLIN;
-    pollfds[2].fd = control;
-    pollfds[2].events = 0;
-
-    while (timeout >= 0) {
-        if (poll(pollfds, 3, timeout ? timeout : -1) == -1 && errno != EINTR) {
-            log_print(FATAL, "Poll() %s", strerror(errno));
-            exit(SYSTEM_ERROR);
-        }
-        if (pollfds[1].revents) {
-            break;
-        }
-        if (pollfds[2].revents) {
-            interrupt(SIGTERM);
-        }
-        timeout = pollfds[0].revents ?
-                the_protocol->process() : the_protocol->timeout();
-#ifdef ANDROID_CHANGES
-        if (!access("/data/misc/vpn/abort", F_OK)) {
-            interrupt(SIGTERM);
-        }
-        if (!timeout) {
-            timeout = 5000;
-        }
-#endif
-    }
-
-    if (timeout < 0) {
-        status = -timeout;
-    } else {
-        int signal;
-        read(signals[0], &signal, sizeof(int));
-        log_print(INFO, "Received signal %d", signal);
-        if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid
-                && WIFEXITED(status)) {
-            status = WEXITSTATUS(status);
-            log_print(INFO, "Pppd is terminated (status = %d)", status);
-            status += PPPD_EXITED;
-            pppd_pid = 0;
-        } else {
-            status = USER_REQUESTED;
-        }
-    }
-
-    stop_pppd();
-    the_protocol->shutdown();
-    log_print(INFO, "Mtpd is terminated (status = %d)", status);
-    return status;
-}
-
-void log_print(int level, char *format, ...)
-{
-    if (level >= 0 && level <= LOG_MAX) {
-#ifdef ANDROID_CHANGES
-        static int levels[5] = {
-            ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN,
-            ANDROID_LOG_ERROR, ANDROID_LOG_FATAL
-        };
-        va_list ap;
-        va_start(ap, format);
-        __android_log_vprint(levels[level], "mtpd", format, ap);
-        va_end(ap);
-#else
-        static char *levels = "DIWEF";
-        va_list ap;
-        fprintf(stderr, "%c: ", levels[level]);
-        va_start(ap, format);
-        vfprintf(stderr, format, ap);
-        va_end(ap);
-        fputc('\n', stderr);
-#endif
-    }
-}
-
-void create_socket(int family, int type, char *server, char *port)
-{
-    struct addrinfo hints = {
-        .ai_flags = AI_NUMERICSERV,
-        .ai_family = family,
-        .ai_socktype = type,
-    };
-    struct addrinfo *records;
-    struct addrinfo *r;
-    int error;
-
-    log_print(INFO, "Connecting to %s port %s via %s", server, port, interface);
-
-    error = getaddrinfo(server, port, &hints, &records);
-    if (error) {
-        log_print(FATAL, "Getaddrinfo() %s", (error == EAI_SYSTEM) ?
-                strerror(errno) : gai_strerror(error));
-        exit(NETWORK_ERROR);
-    }
-
-    for (r = records; r; r = r->ai_next) {
-        int s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
-        if (!setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface,
-                strlen(interface)) && !connect(s, r->ai_addr, r->ai_addrlen)) {
-            the_socket = s;
-            break;
-        }
-        close(s);
-    }
-
-    freeaddrinfo(records);
-
-    if (the_socket == -1) {
-        log_print(FATAL, "Connect() %s", strerror(errno));
-        exit(NETWORK_ERROR);
-    }
-
-#ifdef ANDROID_CHANGES
-    protectFromVpn(the_socket);
-#endif
-
-    fcntl(the_socket, F_SETFD, FD_CLOEXEC);
-    log_print(INFO, "Connection established (socket = %d)", the_socket);
-}
-
-void start_pppd(int pppox)
-{
-    if (pppd_pid) {
-        log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid);
-        close(pppox);
-        return;
-    }
-
-    log_print(INFO, "Starting pppd (pppox = %d)", pppox);
-
-    pppd_pid = fork();
-    if (pppd_pid < 0) {
-        log_print(FATAL, "Fork() %s", strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-
-    if (!pppd_pid) {
-        char *args[pppd_argc + 5];
-        char number[FD_MAX_LEN + 1];
-
-        snprintf(number, FD_MAX_LEN + 1, "%d", pppox);
-        args[0] = "pppd";
-        args[1] = "nodetach";
-        args[2] = "pppox";
-        args[3] = number;
-        memcpy(&args[4], pppd_argv, sizeof(char *) * pppd_argc);
-        args[4 + pppd_argc] = 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);
-    close(pppox);
-}
-
-/**
- * Start pppd daemon with pppol2tp-android plugin.
- *
- * @param tunnel_fd Tunnel socket file descriptor
- * @param session_fd Session socket file descriptor
- * @param tunnel_id Tunnel ID; must be in host byte order
- * @param session_id Session ID; must be in host byte order
- */
-void start_pppd_ol2tp(int tunnel_fd, int session_fd, int tunnel_id,
-                      int session_id)
-{
-    if (pppd_pid) {
-        log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid);
-        goto ret;
-    }
-
-    log_print(INFO, "Starting pppd (tunnel_fd = %d, session_fd = %d)",
-              tunnel_fd, session_fd);
-
-    pppd_pid = fork();
-    if (pppd_pid < 0) {
-        log_print(FATAL, "Fork() %s", strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-
-    if (!pppd_pid) {
-        char tunnel_fd_str[FD_MAX_LEN + 1];
-        char session_fd_str[FD_MAX_LEN + 1];
-        char tunnel_id_str[FD_MAX_LEN + 1];
-        char session_id_str[FD_MAX_LEN + 1];
-
-        snprintf(tunnel_fd_str, FD_MAX_LEN + 1, "%d", tunnel_fd);
-        snprintf(session_fd_str, FD_MAX_LEN + 1, "%d", session_fd);
-        snprintf(tunnel_id_str, FD_MAX_LEN + 1, "%d", tunnel_id);
-        snprintf(session_id_str, FD_MAX_LEN + 1, "%d", session_id);
-
-        const char *l2tp_args[] = {
-            "pppd",
-            "nodetach",
-            "plugin",
-            "pppol2tp-android.so",
-            "session_fd",
-            session_fd_str,
-            "tunnel_fd",
-            tunnel_fd_str,
-            "session_id",
-            session_id_str,
-            "tunnel_id",
-            tunnel_id_str,
-        };
-        const size_t args_len = ARRAY_SIZE(l2tp_args) + pppd_argc + 1;
-        char *args[args_len];
-
-        /* Populate args[] from l2tp_args[] and pppd_argv[] */
-        memcpy(args, l2tp_args, sizeof(l2tp_args));
-        memcpy(args + ARRAY_SIZE(l2tp_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(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);
-}
diff --git a/mtpd.h b/mtpd.h
deleted file mode 100644
index 290a583..0000000
--- a/mtpd.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#ifndef __MTPD_H__
-#define __MTPD_H__
-
-#if !defined(PX_PROTO_OLAC)
-#define USING_UAPI
-#endif
-
-#if defined(USING_UAPI)
-/* This stuff isn't in uapi. */
-#define PX_PROTO_OLAC 3
-#define PX_PROTO_OPNS 4
-
-struct sockaddr_pppopns {
- sa_family_t sa_family;
- unsigned int sa_protocol;
- int tcp_socket;
- uint16_t local;
- uint16_t remote;
-} __attribute__((packed));
-
-struct sockaddr_pppolac {
- sa_family_t sa_family;
- unsigned int sa_protocol;
- int udp_socket;
- struct __attribute__((packed)) {
-   uint16_t tunnel;
-   uint16_t session;
- } local, remote;
-} __attribute__((packed));
-#endif
-
-/* The socket to the server. */
-extern int the_socket;
-
-enum exit_code {
-    SYSTEM_ERROR = 1,
-    NETWORK_ERROR = 2,
-    PROTOCOL_ERROR = 3,
-    CHALLENGE_FAILED = 4,
-    USER_REQUESTED = 5,
-    REMOTE_REQUESTED = 6,
-    PPPD_EXITED = 32,
-};
-
-enum log_level {
-    DEBUG = 0,
-    INFO = 1,
-    WARNING = 2,
-    ERROR = 3,
-    FATAL = 4,
-    LOG_MAX = 4,
-};
-
-void log_print(int level, char *format, ...);
-void create_socket(int family, int type, char *server, char *port);
-void start_pppd(int pppox);
-void start_pppd_ol2tp(int tunnel_fd, int session_fd, int tunnel_id,
-                      int session_id);
-void start_pppd_pptp(int pptp_fd);
-
-/* Each protocol must implement everything defined in this structure. Note that
- * timeout intervals are in milliseconds, where zero means forever. To indicate
- * an error, one should use a negative exit code such as -REMOTE_REQUESTED. */
-struct protocol {
-    /* The name of this protocol. */
-    char *name;
-    /* The number of arguments. */
-    int arguments;
-    /* The usage of the arguments. */
-    char *usage;
-    /* Connect to the server and return the next timeout interval. */
-    int (*connect)(char **arguments);
-    /* Process the incoming packet and return the next timeout interval. */
-    int (*process)();
-    /* Handle the timeout event and return the next timeout interval. */
-    int (*timeout)();
-    /* Handle the shutdown event. */
-    void (*shutdown)();
-};
-
-#endif /* __MTPD_H__ */
diff --git a/mtpd.rc b/mtpd.rc
deleted file mode 100644
index af701d5..0000000
--- a/mtpd.rc
+++ /dev/null
@@ -1,8 +0,0 @@
-service mtpd /system/bin/mtpd
-    class main
-    socket mtpd stream 600 system system
-    user vpn
-    group vpn inet
-    capabilities NET_ADMIN NET_RAW
-    disabled
-    oneshot
diff --git a/pptp.c b/pptp.c
deleted file mode 100644
index 7a58a27..0000000
--- a/pptp.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-/* A simple implementation of PPTP Network Server (RFC 2637) which only
- * creates a single session. The following code only handles control packets.
- * Data packets are handled by PPPoPNS driver which can be found in Android
- * kernel tree. */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <linux/netdevice.h>
-#include <linux/if_pppox.h>
-#include <linux/types.h>
-
-#include "mtpd.h"
-
-enum pptp_message {
-    SCCRQ = 1,
-    SCCRP = 2,
-    STOPCCRQ = 3,
-    STOPCCRP = 4,
-    ECHORQ = 5,
-    ECHORP = 6,
-    OCRQ = 7,
-    OCRP = 8,
-    ICRQ = 9,
-    ICRP = 10,
-    ICCN = 11,
-    CCRQ = 12,
-    CDN = 13,
-    WEN = 14,
-    SLI = 15,
-    MESSAGE_MAX = 15,
-};
-
-static char *messages[] = {
-    NULL, "SCCRQ", "SCCRP", "STOPCCRQ", "STOPCCRP", "ECHORQ", "ECHORP",
-    "OCRQ", "OCRP", "ICRQ", "ICRP", "ICCN", "CCRQ", "CDN", "WEN", "SLI",
-};
-
-static uint8_t lengths[] = {
-    0, 156, 156, 16, 16, 16, 20, 168, 32, 220, 24, 28, 16, 148, 40, 24,
-};
-
-#define CONTROL_MESSAGE         htons(1)
-#define MAGIC_COOKIE            htonl(0x1A2B3C4D)
-#define PROTOCOL_VERSION        htons(0x0100)
-
-#define RESULT_OK               1
-#define RESULT_ERROR            2
-
-/* Some implementation uses 0 instead of 1, so we allow both of them. */
-#define ESTABLISHED(result)     (result <= 1)
-
-#define HEADER_SIZE             8
-#define MIN_MESSAGE_SIZE        10
-
-static __be16 local;
-static __be16 remote;
-static uint16_t state;
-static const char *remote_name;    /* server host name or IP address */
-
-#define MAX_PACKET_LENGTH       220
-
-/* We define all the fields we used in this structure. Type conversion and byte
- * alignment are solved in one place. Although it looks a little bit ugly, it
- * really makes life easier. */
-static struct packet {
-    int length;
-    int expect;
-    union {
-        uint8_t buffer[MAX_PACKET_LENGTH];
-        struct {
-            struct __attribute__((packed)) {
-                uint16_t length;
-                uint16_t type;
-                uint32_t cookie;
-            } header;
-            uint16_t message;
-            uint16_t reserved;
-            union {
-                struct __attribute__((packed)) {
-                    uint16_t protocol_version;
-                    uint8_t result;
-                    uint8_t error;
-                    uint32_t framing;
-                    uint32_t bearer;
-                    uint16_t channels;
-                    uint16_t firmware_revision;
-                    char host[64];
-                } sccrp, sccrq;
-                struct __attribute__((packed)) {
-                    uint16_t call;
-                    uint16_t serial;
-                    uint32_t minimum_speed;
-                    uint32_t maximum_speed;
-                    uint32_t bearer;
-                    uint32_t framing;
-                    uint16_t window_size;
-                } ocrq;
-                struct __attribute__((packed)) {
-                    uint16_t call;
-                    uint16_t peer;
-                    uint8_t result;
-                } ocrp, icrp;
-                struct __attribute__((packed)) {
-                    uint32_t identifier;
-                    uint8_t result;
-                } echorq, echorp;
-                struct __attribute__((packed)) {
-                    uint16_t call;
-                } icrq, ccrq, cdn;
-            };
-        } __attribute__((packed));
-    } __attribute__((aligned(4)));
-} incoming, outgoing;
-
-static void set_message(uint16_t message)
-{
-    uint16_t length = lengths[message];
-    memset(outgoing.buffer, 0, length);
-    outgoing.length = length;
-    outgoing.header.length = htons(length);
-    outgoing.header.type = CONTROL_MESSAGE;
-    outgoing.header.cookie = MAGIC_COOKIE;
-    outgoing.message = htons(message);
-}
-
-static void send_packet()
-{
-    send(the_socket, outgoing.buffer, outgoing.length, 0);
-}
-
-static int recv_packet()
-{
-    int length;
-
-    /* We are going to read a new message if incoming.expect is 0. */
-    if (!incoming.expect) {
-        incoming.length = 0;
-        incoming.expect = HEADER_SIZE;
-    }
-
-    /* The longest message defined in RFC 2637 is 220 bytes, but the protocol
-     * itself allows up to 65536 bytes. Therefore we always read a complete
-     * message but only keep the first 220 bytes before passing up. */
-    length = incoming.expect - incoming.length;
-    if (incoming.length >= MAX_PACKET_LENGTH) {
-        uint8_t buffer[length];
-        length = recv(the_socket, buffer, length, 0);
-    } else {
-        if (incoming.expect > MAX_PACKET_LENGTH) {
-            length = MAX_PACKET_LENGTH - incoming.length;
-        }
-        length = recv(the_socket, &incoming.buffer[incoming.length], length, 0);
-    }
-    if (length == -1) {
-        if (errno == EINTR) {
-            return 0;
-        }
-        log_print(FATAL, "Recv() %s", strerror(errno));
-        exit(NETWORK_ERROR);
-    }
-    if (length == 0) {
-        log_print(DEBUG, "Connection closed");
-        log_print(INFO, "Remote server hung up");
-        return -REMOTE_REQUESTED;
-    }
-    incoming.length += length;
-
-    /* If incoming.header is valid, check cookie and update incoming.expect. */
-    if (incoming.length == HEADER_SIZE && incoming.expect == HEADER_SIZE) {
-        if (incoming.header.cookie != MAGIC_COOKIE) {
-            log_print(DEBUG, "Loss of synchronization");
-            log_print(ERROR, "Protocol error");
-            return -PROTOCOL_ERROR;
-        }
-        incoming.expect = ntohs(incoming.header.length);
-        if (incoming.expect < HEADER_SIZE) {
-            log_print(DEBUG, "Invalid message length");
-            log_print(ERROR, "Protocol error");
-            return -PROTOCOL_ERROR;
-        }
-    }
-
-    /* Now we have a complete message. Reset incoming.expect. */
-    if (incoming.length == incoming.expect) {
-        incoming.expect = 0;
-
-        /* Return 1 if it is a control message. */
-        if (incoming.header.type == CONTROL_MESSAGE) {
-            return 1;
-        }
-        log_print(DEBUG, "Ignored non-control message (type = %u)",
-                (unsigned)ntohs(incoming.header.type));
-    }
-    return 0;
-}
-
-static int pptp_connect(char **arguments)
-{
-    remote_name = arguments[0];
-
-    create_socket(AF_UNSPEC, SOCK_STREAM, arguments[0], arguments[1]);
-
-    log_print(DEBUG, "Sending SCCRQ");
-    state = SCCRQ;
-    set_message(SCCRQ);
-    outgoing.sccrq.protocol_version = PROTOCOL_VERSION;
-    outgoing.sccrq.framing = htonl(3);
-    outgoing.sccrq.bearer = htonl(3);
-    outgoing.sccrq.channels = htons(1);
-    strcpy(outgoing.sccrq.host, "anonymous");
-    send_packet();
-    return 0;
-}
-
-/**
- * Check if upstream kernel implementation of PPTP should be used.
- *
- * @return true If upstream PPTP should be used, which is the case if
- *              the obsolete OPNS feature is not available.
- */
-static bool check_pptp(void)
-{
-    int fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OPNS);
-
-    if (fd < 0) {
-        return true;
-    } else {
-        close(fd);
-        return false;
-    }
-}
-
-/**
- * Create OPNS session.
- *
- * @deprecated It will be removed soon in favor of upstream PPTP.
- *
- * @return PPPoX socket file descriptor
- */
-static int create_pppox_opns(void)
-{
-    int pppox;
-
-    log_print(WARNING, "Using deprecated OPNS protocol. "
-                       "Its support will be removed soon. "
-                       "Please enable PPTP support in your kernel");
-
-    log_print(INFO, "Creating PPPoX socket");
-    pppox = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OPNS);
-
-    if (pppox == -1) {
-        log_print(FATAL, "Socket() %s", strerror(errno));
-        exit(SYSTEM_ERROR);
-    } else {
-        struct sockaddr_pppopns address = {
-            .sa_family = AF_PPPOX,
-            .sa_protocol = PX_PROTO_OPNS,
-            .tcp_socket = the_socket,
-            .local = local,
-            .remote = remote,
-        };
-        if (connect(pppox, (struct sockaddr *)&address, sizeof(address))) {
-            log_print(FATAL, "Connect() %s", strerror(errno));
-            exit(SYSTEM_ERROR);
-        }
-    }
-    return pppox;
-}
-
-/**
- * Get IP address by host name.
- *
- * @param name Host name to get IP address for
- *
- * @return IP address for given host name
- */
-static struct in_addr get_addr_by_name(const char *name)
-{
-    struct addrinfo hints;
-    struct addrinfo *res, *rp;
-    struct in_addr addr;
-    int err;
-
-    memset(&hints, 0, sizeof(struct addrinfo));
-    hints.ai_family = AF_INET;       /* allow only IPv4 */
-    hints.ai_socktype = SOCK_DGRAM;  /* UDP */
-    hints.ai_protocol = 0;           /* any protocol */
-
-    err = getaddrinfo(name, NULL, &hints, &res);
-    if (err) {
-        log_print(FATAL, "%s: getaddrinfo: %s", __func__, gai_strerror(err));
-        exit(SYSTEM_ERROR);
-    }
-
-    for (rp = res; rp != NULL; rp = rp->ai_next) {
-        /* For now we only support IPv4 */
-        if (rp->ai_family == AF_INET) {
-            addr = ((struct sockaddr_in *)rp->ai_addr)->sin_addr;
-            break;
-        }
-    }
-
-    if (rp == NULL) {
-        log_print(FATAL, "%s: No IPv4 addresses found", __func__);
-        freeaddrinfo(res);
-        exit(SYSTEM_ERROR);
-    }
-
-    freeaddrinfo(res);
-
-    return addr;
-}
-
-/**
- * Get local IP address.
- *
- * Make a socket connection with remote server and then call getsockname() on
- * the connected socket. This will return the local IP address.
- *
- * @param remote_addr Server IP address
- *
- * @return Local IP address
- */
-static struct in_addr get_local_addr(struct in_addr remote_addr)
-{
-    int sock;
-    struct sockaddr_in addr;
-    socklen_t addr_len;
-
-    addr_len = sizeof(struct sockaddr_in);
-    addr.sin_addr = remote_addr;
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(0);
-
-    sock = socket(AF_INET, SOCK_DGRAM, 0);
-    if (sock < 0) {
-        log_print(FATAL, "%s: Socket() %s", __func__, strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-
-    if (connect(sock, (struct sockaddr*)&addr, sizeof(addr))) {
-        close(sock);
-        log_print(FATAL, "%s: Connect() %s", __func__, strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-
-    getsockname(sock, (struct sockaddr*)&addr, &addr_len);
-    close(sock);
-
-    return addr.sin_addr;
-}
-
-/**
- * Create PPTP session.
- *
- * @return PPTP socket file descriptor
- */
-static int create_pppox_pptp(void)
-{
-    int pptp_fd;
-    struct sockaddr_pppox src, dst;
-    struct in_addr remote_addr; /* server IP address */
-    struct in_addr local_addr;  /* client IP address */
-
-    remote_addr = get_addr_by_name(remote_name);
-    local_addr = get_local_addr(remote_addr);
-
-    src.sa_family = AF_PPPOX;
-    src.sa_protocol = PX_PROTO_PPTP;
-    src.sa_addr.pptp.call_id = ntohs(local);
-    src.sa_addr.pptp.sin_addr = local_addr;
-
-    dst.sa_family = AF_PPPOX;
-    dst.sa_protocol = PX_PROTO_PPTP;
-    dst.sa_addr.pptp.call_id = ntohs(remote);
-    dst.sa_addr.pptp.sin_addr = remote_addr;
-
-    pptp_fd = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_PPTP);
-    if (pptp_fd < 0) {
-        log_print(FATAL, "Failed to create PPTP socket (%s)", strerror(errno));
-        exit(SYSTEM_ERROR);
-    }
-
-    if (bind(pptp_fd, (struct sockaddr*)&src, sizeof(src))) {
-        log_print(FATAL, "Failed to bind PPTP socket (%s)", strerror(errno));
-        close(pptp_fd);
-        exit(SYSTEM_ERROR);
-    }
-
-    if (connect(pptp_fd, (struct sockaddr*)&dst, sizeof(dst))) {
-        log_print(FATAL, "Failed to connect PPTP socket (%s)", strerror(errno));
-        close(pptp_fd);
-        exit(SYSTEM_ERROR);
-    }
-
-    return pptp_fd;
-}
-
-static int pptp_process()
-{
-    int result = recv_packet();
-    if (result <= 0) {
-        return result;
-    }
-
-    if (incoming.length < MIN_MESSAGE_SIZE) {
-        log_print(DEBUG, "Control message too short");
-        return 0;
-    }
-    incoming.message = ntohs(incoming.message);
-    if (incoming.message > MESSAGE_MAX || !messages[incoming.message]) {
-        log_print(DEBUG, "Received UNKNOWN %d", incoming.message);
-        return 0;
-    }
-    if (incoming.length < lengths[incoming.message]) {
-        log_print(DEBUG, "Received %s with invalid length (length = %d)",
-                messages[incoming.message], incoming.length);
-        return 0;
-    }
-
-    switch(incoming.message) {
-        case SCCRP:
-            if (state == SCCRQ) {
-                if (incoming.sccrp.protocol_version == PROTOCOL_VERSION &&
-                        ESTABLISHED(incoming.sccrp.result)) {
-                    while (!local) {
-                        local = random();
-                    }
-                    log_print(DEBUG, "Received SCCRP -> Sending OCRQ "
-                            "(local = %u)", (unsigned)ntohs(local));
-                    log_print(INFO, "Tunnel established");
-                    state = OCRQ;
-                    set_message(OCRQ);
-                    outgoing.ocrq.call = local;
-                    outgoing.ocrq.serial = random();
-                    outgoing.ocrq.minimum_speed = htonl(1000);
-                    outgoing.ocrq.maximum_speed = htonl(100000000);
-                    outgoing.ocrq.bearer = htonl(3);
-                    outgoing.ocrq.framing = htonl(3);
-                    outgoing.ocrq.window_size = htons(8192);
-                    send_packet();
-                    return 0;
-                }
-                log_print(DEBUG, "Received SCCRP (result = %d)",
-                        incoming.sccrq.result);
-                log_print(INFO, "Remote server hung up");
-                return -REMOTE_REQUESTED;
-            }
-            break;
-
-        case OCRP:
-            if (state == OCRQ && incoming.ocrp.peer == local) {
-                if (ESTABLISHED(incoming.ocrp.result)) {
-                    remote = incoming.ocrp.call;
-                    log_print(DEBUG, "Received OCRQ (remote = %u)",
-                            (unsigned)ntohs(remote));
-                    log_print(INFO, "Session established");
-                    state = OCRP;
-
-                    if (check_pptp())
-                        start_pppd_pptp(create_pppox_pptp());
-                    else
-                        start_pppd(create_pppox_opns());
-
-                    return 0;
-                }
-                log_print(DEBUG, "Received OCRP (result = %d)",
-                        incoming.ocrp.result);
-                log_print(INFO, "Remote server hung up");
-                return -REMOTE_REQUESTED;
-            }
-            break;
-
-        case STOPCCRQ:
-            log_print(DEBUG, "Received STOPCCRQ");
-            log_print(INFO, "Remote server hung up");
-            state = STOPCCRQ;
-            return -REMOTE_REQUESTED;
-
-        case CCRQ:
-            /* According to RFC 2637 page 45, we should never receive CCRQ for
-             * outgoing calls. However, some implementation only acts as PNS and
-             * always uses CCRQ to clear a call, so here we still handle it. */
-            if (state == OCRP && incoming.ccrq.call == remote) {
-                log_print(DEBUG, "Received CCRQ (remote = %u)",
-                        (unsigned)ntohs(remote));
-                log_print(INFO, "Remote server hung up");
-                return -REMOTE_REQUESTED;
-            }
-            break;
-
-        case CDN:
-            if (state == OCRP && incoming.cdn.call == remote) {
-                log_print(DEBUG, "Received CDN (remote = %u)",
-                        (unsigned)ntohs(remote));
-                log_print(INFO, "Remote server hung up");
-                return -REMOTE_REQUESTED;
-            }
-            break;
-
-        case ECHORQ:
-            log_print(DEBUG, "Received ECHORQ -> Sending ECHORP");
-            set_message(ECHORP);
-            outgoing.echorp.identifier = incoming.echorq.identifier;
-            outgoing.echorp.result = RESULT_OK;
-            send_packet();
-            return 0;
-
-        case WEN:
-        case SLI:
-            log_print(DEBUG, "Recevied %s", messages[incoming.message]);
-            return 0;
-
-        case ICRQ:
-            log_print(DEBUG, "Received ICRQ (remote = %u, call = %u) -> "
-                    "Sending ICRP with error", (unsigned)ntohs(remote),
-                    (unsigned)ntohs(incoming.icrq.call));
-            set_message(ICRP);
-            outgoing.icrp.peer = incoming.icrq.call;
-            outgoing.icrp.result = RESULT_ERROR;
-            send_packet();
-            return 0;
-
-        case OCRQ:
-            log_print(DEBUG, "Received OCRQ (remote = %u, call = %u) -> "
-                    "Sending OCRP with error", (unsigned)ntohs(remote),
-                    (unsigned)ntohs(incoming.ocrq.call));
-            set_message(OCRP);
-            outgoing.ocrp.peer = incoming.ocrq.call;
-            outgoing.ocrp.result = RESULT_ERROR;
-            send_packet();
-            return 0;
-    }
-
-    /* We reach here if we got an unexpected message. Just log it. */
-    log_print(DEBUG, "Received UNEXPECTED %s", messages[incoming.message]);
-    return 0;
-}
-
-static int pptp_timeout()
-{
-    return 0;
-}
-
-static void pptp_shutdown()
-{
-    /* Normally we should send STOPCCRQ and wait for STOPCCRP, but this might
-     * block for a long time. Here we simply take the shortcut: do nothing. */
-}
-
-struct protocol pptp = {
-    .name = "pptp",
-    .arguments = 2,
-    .usage = "<server> <port>",
-    .connect = pptp_connect,
-    .process = pptp_process,
-    .timeout = pptp_timeout,
-    .shutdown = pptp_shutdown,
-};