mtpd.c revision 7b66d20359dd1c5586ecb1594d3ee929c5b42624
179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh/* 279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * Copyright (C) 2009 The Android Open Source Project 379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * 479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * you may not use this file except in compliance with the License. 679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * You may obtain a copy of the License at 779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * 879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * 1079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software 1179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 1279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * See the License for the specific language governing permissions and 1479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh * limitations under the License. 1579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh */ 1679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 1779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <stdio.h> 1879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <stdlib.h> 1979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <stdarg.h> 2079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <string.h> 2179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <errno.h> 2279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <sys/types.h> 2379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <sys/socket.h> 2479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <sys/poll.h> 2579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <sys/wait.h> 2679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <netdb.h> 2779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <signal.h> 2879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <unistd.h> 2979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <fcntl.h> 3079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include <time.h> 3179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 3284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 3384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#include <android/log.h> 3484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#include <cutils/sockets.h> 35f102920925b71379dc47cead612b4374d712278aChia-chi Yeh#include "keystore_get.h" 3684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 3784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 3879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh#include "mtpd.h" 3979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 4079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehint the_socket = -1; 4179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 4279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehextern struct protocol l2tp; 43063bb92976a72c53044c1c147fb4d1feec9716eeChia-chi Yehextern struct protocol pptp; 44063bb92976a72c53044c1c147fb4d1feec9716eeChia-chi Yehstatic struct protocol *protocols[] = {&l2tp, &pptp, NULL}; 4579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic struct protocol *the_protocol; 4679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 4779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic int pppd_argc; 4879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic char **pppd_argv; 4979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic pid_t pppd_pid; 5079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 5179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh/* We redirect signals to a pipe in order to prevent race conditions. */ 5279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic int signals[2]; 5379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 5479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic void interrupt(int signal) 5579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 5679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh write(signals[1], &signal, sizeof(int)); 5779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 5879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 5979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic int initialize(int argc, char **argv) 6079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 6179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh int i; 6279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 637b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh for (i = 0; protocols[i]; ++i) { 647b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh struct protocol *p = protocols[i]; 657b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh if (argc - 2 >= p->arguments && !strcmp(argv[1], p->name)) { 667b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh log_print(INFO, "Using protocol %s", p->name); 677b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh the_protocol = p; 6879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh break; 6979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 7079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 7179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 727b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh if (!the_protocol) { 737b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh printf("Usages:\n"); 7479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh for (i = 0; protocols[i]; ++i) { 757b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh struct protocol *p = protocols[i]; 767b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh printf(" %s %s %s pppd-arguments\n", argv[0], p->name, p->usage); 7779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 787b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh exit(0); 7979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 8079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 817b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh pppd_argc = argc - 2 - the_protocol->arguments; 827b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh pppd_argv = &argv[2 + the_protocol->arguments]; 837b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh return the_protocol->connect(&argv[2]); 8479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 8579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 8679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehstatic void stop_pppd() 8779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 8879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pppd_pid) { 8979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Sending signal to pppd (pid = %d)", pppd_pid); 9079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh kill(pppd_pid, SIGTERM); 9179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh sleep(5); 9279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pppd_pid = 0; 9379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 9479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 9579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 9684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 9784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 9884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yehstatic int get_control_and_arguments(int *argc, char ***argv) 9984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh{ 1007b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh static char *args[32]; 10184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int control; 10284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int i; 10384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 104063bb92976a72c53044c1c147fb4d1feec9716eeChia-chi Yeh if ((i = android_get_control_socket("mtpd")) == -1) { 105063bb92976a72c53044c1c147fb4d1feec9716eeChia-chi Yeh return -1; 106063bb92976a72c53044c1c147fb4d1feec9716eeChia-chi Yeh } 10784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(DEBUG, "Waiting for control socket"); 108063bb92976a72c53044c1c147fb4d1feec9716eeChia-chi Yeh if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) { 10984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(FATAL, "Cannot get control socket"); 11084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh exit(SYSTEM_ERROR); 11184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 11284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh close(i); 11384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh fcntl(control, F_SETFD, FD_CLOEXEC); 11484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 11584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[0] = (*argv)[0]; 1167b66d20359dd1c5586ecb1594d3ee929c5b42624Chia-chi Yeh for (i = 1; i < 32; ++i) { 11784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh unsigned char length; 11884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh if (recv(control, &length, 1, 0) != 1) { 11984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(FATAL, "Cannot get argument length"); 12084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh exit(SYSTEM_ERROR); 12184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 12284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh if (length == 0xFF) { 12384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh break; 12484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } else { 12584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int offset = 0; 12684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[i] = malloc(length + 1); 12784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh while (offset < length) { 12884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int n = recv(control, &args[i][offset], length - offset, 0); 12984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh if (n > 0) { 13084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh offset += n; 13184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } else { 13284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(FATAL, "Cannot get argument value"); 13384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh exit(SYSTEM_ERROR); 13484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 13584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 13684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[i][length] = 0; 13784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 13884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh } 13984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(DEBUG, "Received %d arguments", i - 1); 14084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 141f102920925b71379dc47cead612b4374d712278aChia-chi Yeh /* L2TP secret is the only thing stored in keystore. We do the query here 142f102920925b71379dc47cead612b4374d712278aChia-chi Yeh * so other files are clean and free from android specific code. */ 143f102920925b71379dc47cead612b4374d712278aChia-chi Yeh if (i > 4 && !strcmp("l2tp", args[1]) && args[4][0]) { 14458c35fd8e8d71912c64cb55d6e27df50dde65f76Chia-chi Yeh char value[KEYSTORE_MESSAGE_SIZE]; 145e01c97926d16201d90f2a0f1998c1276be459e5cChia-chi Yeh int length = keystore_get(args[4], strlen(args[4]), value); 14658c35fd8e8d71912c64cb55d6e27df50dde65f76Chia-chi Yeh if (length == -1) { 147f102920925b71379dc47cead612b4374d712278aChia-chi Yeh log_print(FATAL, "Cannot get L2TP secret from keystore"); 148f102920925b71379dc47cead612b4374d712278aChia-chi Yeh exit(SYSTEM_ERROR); 149f102920925b71379dc47cead612b4374d712278aChia-chi Yeh } 150f102920925b71379dc47cead612b4374d712278aChia-chi Yeh free(args[4]); 15158c35fd8e8d71912c64cb55d6e27df50dde65f76Chia-chi Yeh args[4] = malloc(length + 1); 15258c35fd8e8d71912c64cb55d6e27df50dde65f76Chia-chi Yeh memcpy(args[4], value, length); 15358c35fd8e8d71912c64cb55d6e27df50dde65f76Chia-chi Yeh args[4][length] = 0; 154f102920925b71379dc47cead612b4374d712278aChia-chi Yeh } 155f102920925b71379dc47cead612b4374d712278aChia-chi Yeh 15684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh *argc = i; 15784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh *argv = args; 15884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh return control; 15984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh} 16084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 16184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 16284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh 16379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehint main(int argc, char **argv) 16479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 16579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh struct pollfd pollfds[2]; 16679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh int timeout; 16784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int status; 16884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 16984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh int control = get_control_and_arguments(&argc, &argv); 170fa04c31da4ef8765c2c8967fe548bcb55d0523d9Chia-chi Yeh unsigned char code = argc - 1; 17184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh send(control, &code, 1, 0); 17284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 17379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 17479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh srandom(time(NULL)); 17579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 17679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pipe(signals) == -1) { 17779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Pipe() %s", strerror(errno)); 17879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(SYSTEM_ERROR); 17979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 1802d24765a7c081b35288838acf2a18724652fae43Chia-chi Yeh fcntl(signals[0], F_SETFD, FD_CLOEXEC); 1812d24765a7c081b35288838acf2a18724652fae43Chia-chi Yeh fcntl(signals[1], F_SETFD, FD_CLOEXEC); 18279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 183a7776544bd4d487667b3e55896432d255209c789Chia-chi Yeh timeout = initialize(argc, argv); 184a7776544bd4d487667b3e55896432d255209c789Chia-chi Yeh 18579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGHUP, interrupt); 18679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGINT, interrupt); 18779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGTERM, interrupt); 18879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGCHLD, interrupt); 18979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh signal(SIGPIPE, SIG_IGN); 19079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh atexit(stop_pppd); 19179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 19279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pollfds[0].fd = signals[0]; 19379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pollfds[0].events = POLLIN; 19479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pollfds[1].fd = the_socket; 19579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pollfds[1].events = POLLIN; 19679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 19779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh while (timeout >= 0) { 19879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (poll(pollfds, 2, timeout ? timeout : -1) == -1 && errno != EINTR) { 19979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Poll() %s", strerror(errno)); 20079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(SYSTEM_ERROR); 20179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 20279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pollfds[0].revents) { 20379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh break; 20479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 20579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh timeout = pollfds[1].revents ? 20679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh the_protocol->process() : the_protocol->timeout(); 20779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 20879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 20979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (timeout < 0) { 21084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh status = -timeout; 21179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } else { 21279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh int signal; 21379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh read(signals[0], &signal, sizeof(int)); 21479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Received signal %d", signal); 21584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid 21684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh && WIFEXITED(status)) { 21784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh status = WEXITSTATUS(status); 21884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(INFO, "Pppd is terminated (status = %d)", status); 21984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh status += PPPD_EXITED; 22079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pppd_pid = 0; 22179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } else { 22284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh status = USER_REQUESTED; 22379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 22479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 22579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 22679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh stop_pppd(); 22779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh the_protocol->shutdown(); 22879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 22984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 23084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh code = status; 23184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh send(control, &code, 1, 0); 23284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 23384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh log_print(INFO, "Mtpd is terminated (status = %d)", status); 23484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh return status; 23579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 23679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 23779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehvoid log_print(int level, char *format, ...) 23879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 23979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (level >= 0 && level <= LOG_MAX) { 24084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#ifdef ANDROID_CHANGES 24184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh static int levels[5] = { 24284e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, 24384e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh ANDROID_LOG_ERROR, ANDROID_LOG_FATAL 24484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh }; 24584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh va_list ap; 24684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh va_start(ap, format); 24784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh __android_log_vprint(levels[level], "mtpd", format, ap); 24884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh va_end(ap); 24984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#else 25084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh static char *levels = "DIWEF"; 25179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh va_list ap; 25279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh fprintf(stderr, "%c: ", levels[level]); 25379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh va_start(ap, format); 25479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh vfprintf(stderr, format, ap); 25579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh va_end(ap); 25679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh fputc('\n', stderr); 25784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh#endif 25879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 25979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 26079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 26179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehvoid create_socket(int family, int type, char *server, char *port) 26279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 26379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh struct addrinfo hints = { 26479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh .ai_flags = AI_NUMERICSERV, 26579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh .ai_family = family, 26679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh .ai_socktype = type, 26779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh }; 26879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh struct addrinfo *records; 26979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh struct addrinfo *r; 27079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh int error; 27179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 27279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Connecting to %s port %s", server, port); 27379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 27479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh error = getaddrinfo(server, port, &hints, &records); 27579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (error) { 27679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Getaddrinfo() %s", (error == EAI_SYSTEM) ? 27779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh strerror(errno) : gai_strerror(error)); 27879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(NETWORK_ERROR); 27979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 28079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 28179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh for (r = records; r; r = r->ai_next) { 28279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh the_socket = socket(r->ai_family, r->ai_socktype, r->ai_protocol); 283a7776544bd4d487667b3e55896432d255209c789Chia-chi Yeh if (the_socket != -1) { 284a7776544bd4d487667b3e55896432d255209c789Chia-chi Yeh if (connect(the_socket, r->ai_addr, r->ai_addrlen) == 0) { 285a7776544bd4d487667b3e55896432d255209c789Chia-chi Yeh break; 286a7776544bd4d487667b3e55896432d255209c789Chia-chi Yeh } 287a7776544bd4d487667b3e55896432d255209c789Chia-chi Yeh close(the_socket); 288fa04c31da4ef8765c2c8967fe548bcb55d0523d9Chia-chi Yeh the_socket = -1; 28979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 29079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 29179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 29279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh freeaddrinfo(records); 29379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 29479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (the_socket == -1) { 29579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Connect() %s", strerror(errno)); 29679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(NETWORK_ERROR); 29779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 29879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 29979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh fcntl(the_socket, F_SETFD, FD_CLOEXEC); 30079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Connection established (socket = %d)", the_socket); 30179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 30279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 30379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yehvoid start_pppd(int pppox) 30479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh{ 30579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pppd_pid) { 30679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid); 30779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh close(pppox); 30879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh return; 30979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 31079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 31179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Starting pppd (pppox = %d)", pppox); 31279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 31379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh pppd_pid = fork(); 31479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (pppd_pid < 0) { 31579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Fork() %s", strerror(errno)); 31679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(SYSTEM_ERROR); 31779e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 31879e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 31979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh if (!pppd_pid) { 32084e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh char *args[pppd_argc + 5]; 32184e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh char number[12]; 32279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 32379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh sprintf(number, "%d", pppox); 32484e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[0] = "pppd"; 32584e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[1] = "nodetach"; 32684e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[2] = "pppox"; 32784e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[3] = number; 32884e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh memcpy(&args[4], pppd_argv, sizeof(char *) * pppd_argc); 32984e3195dffa22e8d1568ef9d70aea4bcbba71a72Chia-chi Yeh args[4 + pppd_argc] = NULL; 33079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 3314a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh#ifdef ANDROID_CHANGES 3324a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh { 3334a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh char envargs[65536]; 3344a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh char *tail = envargs; 3354a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh int i; 3364a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh /* Hex encode the arguments using [A-P] instead of [0-9A-F]. */ 3374a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh for (i = 0; args[i]; ++i) { 3384a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh char *p = args[i]; 3394a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh do { 3404a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh *tail++ = 'A' + ((*p >> 4) & 0x0F); 3414a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh *tail++ = 'A' + (*p & 0x0F); 3424a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh } while (*p++); 3434a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh } 3444a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh *tail = 0; 3454a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh setenv("envargs", envargs, 1); 3464a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh args[1] = NULL; 3474a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh } 3484a721df13a07ca36daafbb3785653979e3d1d393Chia-chi Yeh#endif 34979e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh execvp("pppd", args); 35079e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(FATAL, "Exec() %s", strerror(errno)); 35179e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh exit(1); /* Pretending a fatal error in pppd. */ 35279e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh } 35379e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh 35479e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh log_print(INFO, "Pppd started (pid = %d)", pppd_pid); 35579e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh close(pppox); 35679e6232ffa3765d3352e01e2b7887b6425c7c655Chia-chi Yeh} 357