main.c revision 8f3b38855d8849959825acc45dd11144adc7d862
1/* 2 * Copyright (C) 2011 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 <signal.h> 21#include <poll.h> 22 23#ifdef ANDROID_CHANGES 24#include <unistd.h> 25#include <sys/types.h> 26#include <sys/socket.h> 27#include <android/log.h> 28#include <cutils/sockets.h> 29#include <private/android_filesystem_config.h> 30#endif 31 32#include "config.h" 33#include "gcmalloc.h" 34#include "session.h" 35#include "schedule.h" 36#include "plog.h" 37 38#ifdef ANDROID_CHANGES 39 40static int get_control_and_arguments(int *argc, char ***argv) 41{ 42 static char *args[32]; 43 int control; 44 int i; 45 46 if ((i = android_get_control_socket("racoon")) == -1) { 47 return -1; 48 } 49 do_plog(LLV_DEBUG, "Waiting for control socket"); 50 if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) { 51 do_plog(LLV_ERROR, "Cannot get control socket"); 52 exit(1); 53 } 54 close(i); 55 56 args[0] = (*argv)[0]; 57 for (i = 1; i < 32; ++i) { 58 unsigned char bytes[2]; 59 if (recv(control, &bytes[0], 1, 0) != 1 60 || recv(control, &bytes[1], 1, 0) != 1) { 61 do_plog(LLV_ERROR, "Cannot get argument length"); 62 exit(1); 63 } else { 64 int length = bytes[0] << 8 | bytes[1]; 65 int offset = 0; 66 67 if (length == 0xFFFF) { 68 break; 69 } 70 args[i] = malloc(length + 1); 71 while (offset < length) { 72 int n = recv(control, &args[i][offset], length - offset, 0); 73 if (n > 0) { 74 offset += n; 75 } else { 76 do_plog(LLV_ERROR, "Cannot get argument value"); 77 exit(1); 78 } 79 } 80 args[i][length] = 0; 81 } 82 } 83 do_plog(LLV_DEBUG, "Received %d arguments", i - 1); 84 85 *argc = i; 86 *argv = args; 87 return control; 88} 89 90#endif 91 92extern void setup(int argc, char **argv); 93 94char *pname; 95 96static int monitor_count; 97static struct { 98 int (*callback)(void *ctx, int fd); 99 void *ctx; 100} monitors[10]; 101static struct pollfd pollfds[10]; 102 103static void terminate(int signal) 104{ 105 exit(1); 106} 107 108static void terminated() 109{ 110 do_plog(LLV_INFO, "Bye\n"); 111} 112 113int main(int argc, char **argv) 114{ 115#ifdef ANDROID_CHANGES 116 int control = get_control_and_arguments(&argc, &argv); 117 if (control != -1) { 118 pname = "%p"; 119 } 120#endif 121 122 do_plog(LLV_INFO, "ipsec-tools 0.8.0 (http://ipsec-tools.sf.net)\n"); 123 setup(argc, argv); 124 125 signal(SIGHUP, terminate); 126 signal(SIGINT, terminate); 127 signal(SIGTERM, terminate); 128 signal(SIGPIPE, SIG_IGN); 129 atexit(terminated); 130 131 while (1) { 132 struct timeval *tv = schedular(); 133 int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1; 134 135 if (poll(pollfds, monitor_count, timeout) > 0) { 136 int i; 137 for (i = 0; i < monitor_count; ++i) { 138 if (pollfds[i].revents & POLLHUP) { 139 do_plog(LLV_ERROR, "fd %d is closed\n", pollfds[i].fd); 140 exit(1); 141 } 142 if (pollfds[i].revents & POLLIN) { 143 monitors[i].callback(monitors[i].ctx, pollfds[i].fd); 144 } 145 } 146 } 147 } 148 return 0; 149} 150 151/* session.h */ 152 153void monitor_fd(int fd, int (*callback)(void *, int), void *ctx, int priority) 154{ 155 if (fd < 0 || monitor_count == 10) { 156 do_plog(LLV_ERROR, "Cannot monitor fd"); 157 exit(1); 158 } 159 monitors[monitor_count].callback = callback; 160 monitors[monitor_count].ctx = ctx; 161 pollfds[monitor_count].fd = fd; 162 pollfds[monitor_count].events = POLLIN; 163 ++monitor_count; 164} 165 166void unmonitor_fd(int fd) 167{ 168 exit(1); 169} 170 171/* plog.h */ 172 173void do_plog(int level, char *format, ...) 174{ 175 if (level >= 0 && level <= 5) { 176#ifdef ANDROID_CHANGES 177 static int levels[6] = { 178 ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO, 179 ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE 180 }; 181 va_list ap; 182 va_start(ap, format); 183 __android_log_vprint(levels[level], "racoon", format, ap); 184 va_end(ap); 185#else 186 static char *levels = "EWNIDV"; 187 fprintf(stderr, "%c: ", levels[level]); 188 va_list ap; 189 va_start(ap, format); 190 vfprintf(stderr, format, ap); 191 va_end(ap); 192#endif 193 } 194} 195 196char *binsanitize(char *data, size_t length) 197{ 198 char *output = racoon_malloc(length + 1); 199 if (output) { 200 size_t i; 201 for (i = 0; i < length; ++i) { 202 output[i] = (data[i] < ' ' || data[i] > '~') ? '?' : data[i]; 203 } 204 output[length] = '\0'; 205 } 206 return output; 207} 208