rp-l2tp patches from wl500g.googlecode.com project
[tomato.git] / release / src / router / rp-l2tp / utils.c
blobf09fe5d32b7a448f7eac051479eccfb5056672b8
1 /***********************************************************************
3 * utils.c
5 * Utility functions for l2tp
7 * Copyright (C) 2002 Roaring Penguin Software Inc.
9 * This software may be distributed under the terms of the GNU General
10 * Public License, Version 2, or (at your option) any later version.
12 * LIC: GPL
14 ***********************************************************************/
16 static char const RCSID[] =
17 "$Id: utils.c,v 1.1.48.1 2005/08/08 12:05:25 honor Exp $";
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <time.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <dlfcn.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <syslog.h>
32 #include "l2tp.h"
34 #define MAX_ERRMSG_LEN 512
36 static int random_fd = -1;
37 static char errmsg[MAX_ERRMSG_LEN];
39 struct sd_handler {
40 l2tp_shutdown_func f;
41 void *data;
44 static struct sd_handler shutdown_handlers[16];
46 static int n_shutdown_handlers = 0;
48 int
49 l2tp_register_shutdown_handler(l2tp_shutdown_func f, void *data)
51 if (n_shutdown_handlers == 16) return -1;
52 shutdown_handlers[n_shutdown_handlers].f = f;
53 shutdown_handlers[n_shutdown_handlers].data = data;
54 n_shutdown_handlers++;
55 return n_shutdown_handlers;
58 void
59 l2tp_cleanup(void)
61 int i;
62 for (i=0; i<n_shutdown_handlers; i++) {
63 shutdown_handlers[i].f(shutdown_handlers[i].data);
67 char const *
68 l2tp_get_errmsg(void)
70 return errmsg;
73 /**********************************************************************
74 * %FUNCTION: set_errmsg
75 * %ARGUMENTS:
76 * fmt -- printf format
77 * ... -- format args
78 * %RETURNS:
79 * Nothing
80 * %DESCRIPTION:
81 * Sets static errmsg string
82 ***********************************************************************/
83 void
84 l2tp_set_errmsg(char const *fmt, ...)
86 va_list ap;
87 va_start(ap, fmt);
88 vsnprintf(errmsg, MAX_ERRMSG_LEN, fmt, ap);
89 va_end(ap);
90 errmsg[MAX_ERRMSG_LEN-1] = 0;
91 fprintf(stderr, "Error: %s\n", errmsg);
93 vsyslog(LOG_ERR, fmt, ap);
96 /**********************************************************************
97 * %FUNCTION: random_init
98 * %ARGUMENTS:
99 * None
100 * %RETURNS:
101 * Nothing
102 * %DESCRIPTION:
103 * Sets up random-number generator
104 ***********************************************************************/
105 void
106 l2tp_random_init(void)
108 /* Prefer /dev/urandom; fall back on rand() */
109 random_fd = open("/dev/urandom", O_RDONLY);
110 if (random_fd < 0) {
111 srand(time(NULL) + getpid()*getppid());
116 /**********************************************************************
117 * %FUNCTION: bad random_fill
118 * %ARGUMENTS:
119 * ptr -- pointer to a buffer
120 * size -- size of buffer
121 * %RETURNS:
122 * Nothing
123 * %DESCRIPTION:
124 * Fills buffer with "size" random bytes. This function is not
125 * cryptographically strong; it's used as a fallback for systems
126 * without /dev/urandom.
127 ***********************************************************************/
128 static void
129 bad_random_fill(void *ptr, size_t size)
131 unsigned char *buf = ptr;
132 while(size--) {
133 *buf++ = rand() & 0xFF;
137 /**********************************************************************
138 * %FUNCTION: random_fill
139 * %ARGUMENTS:
140 * ptr -- pointer to a buffer
141 * size -- size of buffer
142 * %RETURNS:
143 * Nothing
144 * %DESCRIPTION:
145 * Fills buffer with "size" random bytes.
146 ***********************************************************************/
147 void
148 l2tp_random_fill(void *ptr, size_t size)
150 int n;
151 int ndone = 0;
152 int nleft = size;
153 unsigned char *buf = ptr;
155 if (random_fd < 0) {
156 bad_random_fill(ptr, size);
157 return;
160 while(nleft) {
161 n = read(random_fd, buf+ndone, nleft);
162 if (n <= 0) {
163 close(random_fd);
164 random_fd = -1;
165 bad_random_fill(buf+ndone, nleft);
166 return;
168 nleft -= n;
169 ndone += n;
173 void l2tp_die(void)
175 fprintf(stderr, "FATAL: %s\n", errmsg);
176 l2tp_cleanup();
177 exit(1);
180 /**********************************************************************
181 * %FUNCTION: load_handler
182 * %ARGUMENTS:
183 * fname -- filename to load
184 * %RETURNS:
185 * -1 on error, 0 if OK
186 * %DESCRIPTION:
187 * Dynamically-loads a handler and initializes it. If fname is not
188 * an absolute path name, we load the handler from /usr/lib/l2tp/plugins
189 ***********************************************************************/
191 l2tp_load_handler(EventSelector *es,
192 char const *fname)
194 char buf[1024];
195 void *handle;
196 void *init;
197 void (*init_fn)(EventSelector *);
199 if (*fname == '/') {
200 handle = dlopen(fname, RTLD_NOW);
201 } else {
202 snprintf(buf, sizeof(buf), "%s/lib/l2tp/%s", PREFIX, fname); //2005-04-14 by kanki
203 buf[sizeof(buf)-1] = 0;
204 handle = dlopen(buf, RTLD_NOW);
207 if (!handle) {
208 l2tp_set_errmsg("Could not dload %s: %s",
209 fname, dlerror());
210 return -1;
213 init = dlsym(handle, "handler_init");
214 if (!init) {
215 dlclose(handle);
216 l2tp_set_errmsg("No handler_init found in %s", fname);
217 return -1;
219 init_fn = (void (*)(EventSelector *)) init;
220 init_fn(es);
221 return 0;