Tomato 1.26 beta(1766)
[tomato/tomato-null.git] / release / src / router / rp-l2tp / utils.c
blobc05bd4255db2cd8574914698b3fa55d7bd9b6dab
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>
31 #include "l2tp.h"
33 #define MAX_ERRMSG_LEN 512
35 static int random_fd = -1;
36 static char errmsg[MAX_ERRMSG_LEN];
38 struct sd_handler {
39 l2tp_shutdown_func f;
40 void *data;
43 static struct sd_handler shutdown_handlers[16];
45 static int n_shutdown_handlers = 0;
47 int
48 l2tp_register_shutdown_handler(l2tp_shutdown_func f, void *data)
50 if (n_shutdown_handlers == 16) return -1;
51 shutdown_handlers[n_shutdown_handlers].f = f;
52 shutdown_handlers[n_shutdown_handlers].data = data;
53 n_shutdown_handlers++;
54 return n_shutdown_handlers;
57 void
58 l2tp_cleanup(void)
60 int i;
61 for (i=0; i<n_shutdown_handlers; i++) {
62 shutdown_handlers[i].f(shutdown_handlers[i].data);
66 char const *
67 l2tp_get_errmsg(void)
69 return errmsg;
72 /**********************************************************************
73 * %FUNCTION: set_errmsg
74 * %ARGUMENTS:
75 * fmt -- printf format
76 * ... -- format args
77 * %RETURNS:
78 * Nothing
79 * %DESCRIPTION:
80 * Sets static errmsg string
81 ***********************************************************************/
82 void
83 l2tp_set_errmsg(char const *fmt, ...)
85 va_list ap;
86 va_start(ap, fmt);
87 vsnprintf(errmsg, MAX_ERRMSG_LEN, fmt, ap);
88 va_end(ap);
89 errmsg[MAX_ERRMSG_LEN-1] = 0;
90 fprintf(stderr, "Error: %s\n", errmsg);
93 /**********************************************************************
94 * %FUNCTION: random_init
95 * %ARGUMENTS:
96 * None
97 * %RETURNS:
98 * Nothing
99 * %DESCRIPTION:
100 * Sets up random-number generator
101 ***********************************************************************/
102 void
103 l2tp_random_init(void)
105 /* Prefer /dev/urandom; fall back on rand() */
106 random_fd = open("/dev/urandom", O_RDONLY);
107 if (random_fd < 0) {
108 srand(time(NULL) + getpid()*getppid());
113 /**********************************************************************
114 * %FUNCTION: bad random_fill
115 * %ARGUMENTS:
116 * ptr -- pointer to a buffer
117 * size -- size of buffer
118 * %RETURNS:
119 * Nothing
120 * %DESCRIPTION:
121 * Fills buffer with "size" random bytes. This function is not
122 * cryptographically strong; it's used as a fallback for systems
123 * without /dev/urandom.
124 ***********************************************************************/
125 static void
126 bad_random_fill(void *ptr, size_t size)
128 unsigned char *buf = ptr;
129 while(size--) {
130 *buf++ = rand() & 0xFF;
134 /**********************************************************************
135 * %FUNCTION: random_fill
136 * %ARGUMENTS:
137 * ptr -- pointer to a buffer
138 * size -- size of buffer
139 * %RETURNS:
140 * Nothing
141 * %DESCRIPTION:
142 * Fills buffer with "size" random bytes.
143 ***********************************************************************/
144 void
145 l2tp_random_fill(void *ptr, size_t size)
147 int n;
148 int ndone = 0;
149 int nleft = size;
150 unsigned char *buf = ptr;
152 if (random_fd < 0) {
153 bad_random_fill(ptr, size);
154 return;
157 while(nleft) {
158 n = read(random_fd, buf+ndone, nleft);
159 if (n <= 0) {
160 close(random_fd);
161 random_fd = -1;
162 bad_random_fill(buf+ndone, nleft);
163 return;
165 nleft -= n;
166 ndone += n;
170 void l2tp_die(void)
172 fprintf(stderr, "FATAL: %s\n", errmsg);
173 l2tp_cleanup();
174 exit(1);
177 /**********************************************************************
178 * %FUNCTION: load_handler
179 * %ARGUMENTS:
180 * fname -- filename to load
181 * %RETURNS:
182 * -1 on error, 0 if OK
183 * %DESCRIPTION:
184 * Dynamically-loads a handler and initializes it. If fname is not
185 * an absolute path name, we load the handler from /usr/lib/l2tp/plugins
186 ***********************************************************************/
188 l2tp_load_handler(EventSelector *es,
189 char const *fname)
191 char buf[1024];
192 void *handle;
193 void *init;
194 void (*init_fn)(EventSelector *);
196 if (*fname == '/') {
197 handle = dlopen(fname, RTLD_NOW);
198 } else {
199 snprintf(buf, sizeof(buf), "%s/lib/l2tp/%s", PREFIX, fname); //2005-04-14 by kanki
200 buf[sizeof(buf)-1] = 0;
201 handle = dlopen(buf, RTLD_NOW);
204 if (!handle) {
205 l2tp_set_errmsg("Could not dload %s: %s",
206 fname, dlerror());
207 return -1;
210 init = dlsym(handle, "handler_init");
211 if (!init) {
212 dlclose(handle);
213 l2tp_set_errmsg("No handler_init found in %s", fname);
214 return -1;
216 init_fn = (void (*)(EventSelector *)) init;
217 init_fn(es);
218 return 0;