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