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 timeout = pollfds[0].revents ? 203 the_protocol->process() : the_protocol->timeout(); 204 #ifdef ANDROID_CHANGES 205 if (!access("/data/misc/vpn/abort", F_OK)) { 206 interrupt(SIGTERM); 207 } 208 if (!timeout) { 209 timeout = 5000; 210 } 211 #endif 212 } 213 214 if (timeout < 0) { 215 status = -timeout; 216 } else { 217 int signal; 218 read(signals[0], &signal, sizeof(int)); 219 log_print(INFO, "Received signal %d", signal); 220 if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid 221 && WIFEXITED(status)) { 222 status = WEXITSTATUS(status); 223 log_print(INFO, "Pppd is terminated (status = %d)", status); 224 status += PPPD_EXITED; 225 pppd_pid = 0; 226 } else { 227 status = USER_REQUESTED; 228 } 229 } 230 231 stop_pppd(); 232 the_protocol->shutdown(); 233 log_print(INFO, "Mtpd is terminated (status = %d)", status); 234 return status; 235 } 236 237 void log_print(int level, char *format, ...) 238 { 239 if (level >= 0 && level <= LOG_MAX) { 240 #ifdef ANDROID_CHANGES 241 static int levels[5] = { 242 ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, 243 ANDROID_LOG_ERROR, ANDROID_LOG_FATAL 244 }; 245 va_list ap; 246 va_start(ap, format); 247 __android_log_vprint(levels[level], "mtpd", format, ap); 248 va_end(ap); 249 #else 250 static char *levels = "DIWEF"; 251 va_list ap; 252 fprintf(stderr, "%c: ", levels[level]); 253 va_start(ap, format); 254 vfprintf(stderr, format, ap); 255 va_end(ap); 256 fputc('\n', stderr); 257 #endif 258 } 259 } 260 261 void create_socket(int family, int type, char *server, char *port) 262 { 263 struct addrinfo hints = { 264 .ai_flags = AI_NUMERICSERV, 265 .ai_family = family, 266 .ai_socktype = type, 267 }; 268 struct addrinfo *records; 269 struct addrinfo *r; 270 int error; 271 272 log_print(INFO, "Connecting to %s port %s via %s", server, port, interface); 273 274 error = getaddrinfo(server, port, &hints, &records); 275 if (error) { 276 log_print(FATAL, "Getaddrinfo() %s", (error == EAI_SYSTEM) ? 277 strerror(errno) : gai_strerror(error)); 278 exit(NETWORK_ERROR); 279 } 280 281 for (r = records; r; r = r->ai_next) { 282 int s = socket(r->ai_family, r->ai_socktype, r->ai_protocol); 283 if (!setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface, 284 strlen(interface)) && !connect(s, r->ai_addr, r->ai_addrlen)) { 285 the_socket = s; 286 break; 287 } 288 close(s); 289 } 290 291 freeaddrinfo(records); 292 293 if (the_socket == -1) { 294 log_print(FATAL, "Connect() %s", strerror(errno)); 295 exit(NETWORK_ERROR); 296 } 297 298 fcntl(the_socket, F_SETFD, FD_CLOEXEC); 299 log_print(INFO, "Connection established (socket = %d)", the_socket); 300 } 301 302 void start_pppd(int pppox) 303 { 304 if (pppd_pid) { 305 log_print(WARNING, "Pppd is already started (pid = %d)", pppd_pid); 306 close(pppox); 307 return; 308 } 309 310 log_print(INFO, "Starting pppd (pppox = %d)", pppox); 311 312 pppd_pid = fork(); 313 if (pppd_pid < 0) { 314 log_print(FATAL, "Fork() %s", strerror(errno)); 315 exit(SYSTEM_ERROR); 316 } 317 318 if (!pppd_pid) { 319 char *args[pppd_argc + 5]; 320 char number[12]; 321 322 sprintf(number, "%d", pppox); 323 args[0] = "pppd"; 324 args[1] = "nodetach"; 325 args[2] = "pppox"; 326 args[3] = number; 327 memcpy(&args[4], pppd_argv, sizeof(char *) * pppd_argc); 328 args[4 + pppd_argc] = NULL; 329 330 #ifdef ANDROID_CHANGES 331 { 332 char envargs[65536]; 333 char *tail = envargs; 334 int i; 335 /* Hex encode the arguments using [A-P] instead of [0-9A-F]. */ 336 for (i = 0; args[i]; ++i) { 337 char *p = args[i]; 338 do { 339 *tail++ = 'A' + ((*p >> 4) & 0x0F); 340 *tail++ = 'A' + (*p & 0x0F); 341 } while (*p++); 342 } 343 *tail = 0; 344 setenv("envargs", envargs, 1); 345 args[1] = NULL; 346 } 347 #endif 348 execvp("pppd", args); 349 log_print(FATAL, "Exec() %s", strerror(errno)); 350 exit(1); /* Pretending a fatal error in pppd. */ 351 } 352 353 log_print(INFO, "Pppd started (pid = %d)", pppd_pid); 354 close(pppox); 355 } 356