1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <stdarg.h> 20 #include <string.h> 21 #include <errno.h> 22 #include <sys/types.h> 23 #include <sys/socket.h> 24 #include <sys/poll.h> 25 #include <sys/wait.h> 26 #include <netdb.h> 27 #include <signal.h> 28 #include <unistd.h> 29 #include <fcntl.h> 30 #include <time.h> 31 32 #ifdef ANDROID_CHANGES 33 #include <android/log.h> 34 #include <cutils/sockets.h> 35 #endif 36 37 #include "mtpd.h" 38 39 int the_socket = -1; 40 41 extern struct protocol l2tp; 42 extern struct protocol pptp; 43 static struct protocol *protocols[] = {&l2tp, &pptp, NULL}; 44 static struct protocol *the_protocol; 45 46 static char *interface; 47 static int pppd_argc; 48 static char **pppd_argv; 49 static pid_t pppd_pid; 50 51 /* We redirect signals to a pipe in order to prevent race conditions. */ 52 static int signals[2]; 53 54 static void interrupt(int signal) 55 { 56 write(signals[1], &signal, sizeof(int)); 57 } 58 59 static int initialize(int argc, char **argv) 60 { 61 int i; 62 63 for (i = 0; protocols[i]; ++i) { 64 struct protocol *p = protocols[i]; 65 if (argc - 3 >= p->arguments && !strcmp(argv[2], p->name)) { 66 log_print(INFO, "Using protocol %s", p->name); 67 the_protocol = p; 68 break; 69 } 70 } 71 72 if (!the_protocol) { 73 printf("Usages:\n"); 74 for (i = 0; protocols[i]; ++i) { 75 struct protocol *p = protocols[i]; 76 printf(" %s interface %s %s pppd-arguments\n", 77 argv[0], p->name, p->usage); 78 } 79 exit(0); 80 } 81 82 interface = argv[1]; 83 pppd_argc = argc - 3 - the_protocol->arguments; 84 pppd_argv = &argv[3 + the_protocol->arguments]; 85 return the_protocol->connect(&argv[3]); 86 } 87 88 static void stop_pppd() 89 { 90 if (pppd_pid) { 91 int status; 92 log_print(INFO, "Sending signal to pppd (pid = %d)", pppd_pid); 93 kill(pppd_pid, SIGTERM); 94 waitpid(pppd_pid, &status, 0); 95 pppd_pid = 0; 96 } 97 } 98 99 #ifdef ANDROID_CHANGES 100 101 static int android_get_control_and_arguments(int *argc, char ***argv) 102 { 103 static char *args[32]; 104 int control; 105 int i; 106 107 if ((i = android_get_control_socket("mtpd")) == -1) { 108 return -1; 109 } 110 log_print(DEBUG, "Waiting for control socket"); 111 if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) { 112 log_print(FATAL, "Cannot get control socket"); 113 exit(SYSTEM_ERROR); 114 } 115 close(i); 116 fcntl(control, F_SETFD, FD_CLOEXEC); 117 118 args[0] = (*argv)[0]; 119 for (i = 1; i < 32; ++i) { 120 unsigned char bytes[2]; 121 if (recv(control, &bytes[0], 1, 0) != 1 || 122 recv(control, &bytes[1], 1, 0) != 1) { 123 log_print(FATAL, "Cannot get argument length"); 124 exit(SYSTEM_ERROR); 125 } else { 126 int length = bytes[0] << 8 | bytes[1]; 127 int offset = 0; 128 129 if (length == 0xFFFF) { 130 break; 131 } 132 args[i] = malloc(length + 1); 133 while (offset < length) { 134 int n = recv(control, &args[i][offset], length - offset, 0); 135 if (n > 0) { 136 offset += n; 137 } else { 138 log_print(FATAL, "Cannot get argument value"); 139 exit(SYSTEM_ERROR); 140 } 141 } 142 args[i][length] = 0; 143 } 144 } 145 log_print(DEBUG, "Received %d arguments", i - 1); 146 147 *argc = i; 148 *argv = args; 149 return control; 150 } 151 152 #endif 153 154 int main(int argc, char **argv) 155 { 156 struct pollfd pollfds[3]; 157 int control = -1; 158 int timeout; 159 int status; 160 161 #ifdef ANDROID_CHANGES 162 control = android_get_control_and_arguments(&argc, &argv); 163 shutdown(control, SHUT_WR); 164 #endif 165 166 srandom(time(NULL)); 167 168 if (pipe(signals) == -1) { 169 log_print(FATAL, "Pipe() %s", strerror(errno)); 170 exit(SYSTEM_ERROR); 171 } 172 fcntl(signals[0], F_SETFD, FD_CLOEXEC); 173 fcntl(signals[1], F_SETFD, FD_CLOEXEC); 174 175 timeout = initialize(argc, argv); 176 177 signal(SIGHUP, interrupt); 178 signal(SIGINT, interrupt); 179 signal(SIGTERM, interrupt); 180 signal(SIGCHLD, interrupt); 181 signal(SIGPIPE, SIG_IGN); 182 atexit(stop_pppd); 183 184 pollfds[0].fd = the_socket; 185 pollfds[0].events = POLLIN; 186 pollfds[1].fd = signals[0]; 187 pollfds[1].events = POLLIN; 188 pollfds[2].fd = control; 189 pollfds[2].events = 0; 190 191 while (timeout >= 0) { 192 if (poll(pollfds, 3, timeout ? timeout : -1) == -1 && errno != EINTR) { 193 log_print(FATAL, "Poll() %s", strerror(errno)); 194 exit(SYSTEM_ERROR); 195 } 196 if (pollfds[1].revents) { 197 break; 198 } 199 if (pollfds[2].revents) { 200 interrupt(SIGTERM); 201 } 202 #ifdef ANDROID_CHANGES 203 if (!access("/data/misc/vpn/abort", F_OK)) { 204 interrupt(SIGTERM); 205 } 206 #endif 207 timeout = pollfds[0].revents ? 208 the_protocol->process() : the_protocol->timeout(); 209 } 210 211 if (timeout < 0) { 212 status = -timeout; 213 } else { 214 int signal; 215 read(signals[0], &signal, sizeof(int)); 216 log_print(INFO, "Received signal %d", signal); 217 if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid 218 && WIFEXITED(status)) { 219 status = WEXITSTATUS(status); 220 log_print(INFO, "Pppd is terminated (status = %d)", status); 221 status += PPPD_EXITED; 222 pppd_pid = 0; 223 } else { 224 status = USER_REQUESTED; 225 } 226 } 227 228 stop_pppd(); 229 the_protocol->shutdown(); 230 log_print(INFO, "Mtpd is terminated (status = %d)", status); 231 return status; 232 } 233 234 void log_print(int level, char *format, ...) 235 { 236 if (level >= 0 && level <= LOG_MAX) { 237 #ifdef ANDROID_CHANGES 238 static int levels[5] = { 239 ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, 240 ANDROID_LOG_ERROR, ANDROID_LOG_FATAL 241 }; 242 va_list ap; 243 va_start(ap, format); 244 __android_log_vprint(levels[level], "mtpd", format, ap); 245 va_end(ap); 246 #else 247 static char *levels = "DIWEF"; 248 va_list ap; 249 fprintf(stderr, "%c: ", levels[level]); 250 va_start(ap, format); 251 vfprintf(stderr, format, ap); 252 va_end(ap); 253 fputc('\n', stderr); 254 #endif 255 } 256 } 257 258 void create_socket(int family, int type, char *server, char *port) 259 { 260 struct addrinfo hints = { 261 .ai_flags = AI_NUMERICSERV, 262 .ai_family = family, 263 .ai_socktype = type, 264 }; 265 struct addrinfo *records; 266 struct addrinfo *r; 267 int error; 268 269 log_print(INFO, "Connecting to %s port %s via %s", server, port, interface); 270 271 error = getaddrinfo(server, port, &hints, &records); 272 if (error) { 273 log_print(FATAL, "Getaddrinfo() %s", (error == EAI_SYSTEM) ? 274 strerror(errno) : gai_strerror(error)); 275 exit(NETWORK_ERROR); 276 } 277 278 for (r = records; r; r = r->ai_next) { 279 int s = socket(r->ai_family, r->ai_socktype, r->ai_protocol); 280 if (!setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface, 281 strlen(interface)) && !connect(s, r->ai_addr, r->ai_addrlen)) { 282 the_socket = s; 283 break; 284 } 285 close(s); 286 } 287 288 freeaddrinfo(records); 289 290 if (the_socket == -1) { 291 log_print(FATAL, "Connect() %s", strerror(errno)); 292 exit(NETWORK_ERROR); 293 } 294 295 fcntl(the_socket, F_SETFD, FD_CLOEXEC); 296 log_print(INFO, "Connection established (socket = %d)", the_socket); 297 } 298 299 void start_pppd(int pppox) 300 { 301 if (pppd_pid) { 302 log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid); 303 close(pppox); 304 return; 305 } 306 307 log_print(INFO, "Starting pppd (pppox = %d)", pppox); 308 309 pppd_pid = fork(); 310 if (pppd_pid < 0) { 311 log_print(FATAL, "Fork() %s", strerror(errno)); 312 exit(SYSTEM_ERROR); 313 } 314 315 if (!pppd_pid) { 316 char *args[pppd_argc + 5]; 317 char number[12]; 318 319 sprintf(number, "%d", pppox); 320 args[0] = "pppd"; 321 args[1] = "nodetach"; 322 args[2] = "pppox"; 323 args[3] = number; 324 memcpy(&args[4], pppd_argv, sizeof(char *) * pppd_argc); 325 args[4 + pppd_argc] = NULL; 326 327 #ifdef ANDROID_CHANGES 328 { 329 char envargs[65536]; 330 char *tail = envargs; 331 int i; 332 /* Hex encode the arguments using [A-P] instead of [0-9A-F]. */ 333 for (i = 0; args[i]; ++i) { 334 char *p = args[i]; 335 do { 336 *tail++ = 'A' + ((*p >> 4) & 0x0F); 337 *tail++ = 'A' + (*p & 0x0F); 338 } while (*p++); 339 } 340 *tail = 0; 341 setenv("envargs", envargs, 1); 342 args[1] = NULL; 343 } 344 #endif 345 execvp("pppd", args); 346 log_print(FATAL, "Exec() %s", strerror(errno)); 347 exit(1); /* Pretending a fatal error in pppd. */ 348 } 349 350 log_print(INFO, "Pppd started (pid = %d)", pppd_pid); 351 close(pppox); 352 } 353