Merge branch 'Teaman-ND' into Teaman-RT
[tomato.git] / release / src / router / xl2tpd / misc.c
blob3092401efe734752e1fc0254444dcb2f887f9be7
1 /*
2 * Layer Two Tunnelling Protocol Daemon
3 * Copyright (C) 1998 Adtran, Inc.
4 * Copyright (C) 2002 Jeff McAdams
6 * Mark Spencer
8 * This software is distributed under the terms
9 * of the GPL, which you should have received
10 * along with this source.
12 * Miscellaneous but important functions
16 #include <unistd.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <syslog.h>
26 #if defined(SOLARIS)
27 # include <varargs.h>
28 #endif
29 #include <netinet/in.h>
30 #include "l2tp.h"
32 /* prevent deadlock that occurs when a signal handler, which interrupted a
33 * call to syslog(), attempts to call syslog(). */
34 static int syslog_nesting = 0;
35 #define SYSLOG_CALL(code) do { \
36 if (++syslog_nesting < 2) { \
37 code; \
38 } \
39 --syslog_nesting; \
40 } while(0)
42 void init_log()
44 static int logopen=0;
46 if(!logopen) {
47 SYSLOG_CALL( openlog (BINARY, LOG_PID, LOG_DAEMON) );
48 logopen=1;
52 void l2tp_log (int level, const char *fmt, ...)
54 char buf[2048];
55 va_list args;
56 va_start (args, fmt);
57 vsnprintf (buf, sizeof (buf), fmt, args);
58 va_end (args);
60 if(gconfig.daemon) {
61 init_log();
62 SYSLOG_CALL( syslog (level, "%s", buf) );
63 } else {
64 fprintf(stderr, "xl2tpd[%d]: %s", getpid(), buf);
68 void set_error (struct call *c, int error, const char *fmt, ...)
70 va_list args;
71 va_start (args, fmt);
72 c->error = error;
73 c->result = RESULT_ERROR;
74 c->needclose = -1;
75 vsnprintf (c->errormsg, sizeof (c->errormsg), fmt, args);
76 if (c->errormsg[strlen (c->errormsg) - 1] == '\n')
77 c->errormsg[strlen (c->errormsg) - 1] = 0;
78 va_end (args);
81 struct buffer *new_buf (int size)
83 struct buffer *b = malloc (sizeof (struct buffer));
85 if (!b || !size || size < 0)
86 return NULL;
87 b->rstart = malloc (size);
88 if (!b->rstart)
90 free (b);
91 return NULL;
93 b->start = b->rstart;
94 b->rend = b->rstart + size - 1;
95 b->len = size;
96 b->maxlen = size;
97 return b;
100 inline void recycle_buf (struct buffer *b)
102 b->start = b->rstart;
103 b->len = b->maxlen;
106 #define bufferDumpWIDTH 16
107 void bufferDump (unsigned char *buf, int buflen)
109 int i = 0, j = 0;
110 /* we need TWO characters to DISPLAY ONE byte */
111 char line[2 * bufferDumpWIDTH + 1], *c;
113 for (i = 0; i < buflen / bufferDumpWIDTH; i++)
115 c = line;
116 for (j = 0; j < bufferDumpWIDTH; j++)
118 sprintf (c, "%02x", (buf[i * bufferDumpWIDTH + j]) & 0xff);
119 c++;
120 c++; /* again two characters to display ONE byte */
122 *c = '\0';
123 l2tp_log (LOG_WARNING,
124 "%s: buflen=%d, buffer[%d]: *%s*\n", __FUNCTION__,
125 buflen, i, line);
128 c = line;
129 for (j = 0; j < buflen % bufferDumpWIDTH; j++)
131 sprintf (c, "%02x",
132 buf[(buflen / bufferDumpWIDTH) * bufferDumpWIDTH +
133 j] & 0xff);
134 c++;
135 c++;
137 if (c != line)
139 *c = '\0';
140 l2tp_log (LOG_WARNING,
141 "%s: buffer[%d]: *%s*\n", __FUNCTION__, i,
142 line);
146 void do_packet_dump (struct buffer *buf)
148 int x;
149 unsigned char *c = buf->start;
150 printf ("packet dump: \nHEX: { ");
151 for (x = 0; x < buf->len; x++)
153 printf ("%.2X ", *c);
154 c++;
156 printf ("}\nASCII: { ");
157 c = buf->start;
158 for (x = 0; x < buf->len; x++)
160 if (*c > 31 && *c < 127)
162 putchar (*c);
164 else
166 putchar (' ');
168 c++;
170 printf ("}\n");
173 inline void swaps (void *buf_v, int len)
175 #ifdef __alpha
176 /* Reverse byte order alpha is little endian so lest save a step.
177 to make things work out easier */
178 int x;
179 unsigned char t1;
180 unsigned char *tmp = (_u16 *) buf_v;
181 for (x = 0; x < len; x += 2)
183 t1 = tmp[x];
184 tmp[x] = tmp[x + 1];
185 tmp[x + 1] = t1;
187 #else
189 /* Reverse byte order (if proper to do so)
190 to make things work out easier */
191 int x;
192 struct hw { _u16 s; } __attribute__ ((packed)) *p = (struct hw *) buf_v;
193 for (x = 0; x < len / 2; x++, p++)
194 p->s = ntohs(p->s);
195 #endif
200 inline void toss (struct buffer *buf)
203 * Toss a frame and free up the buffer that contained it
206 free (buf->rstart);
207 free (buf);
210 inline void safe_copy (char *a, char *b, int size)
212 /* Copies B into A (assuming A holds MAXSTRLEN bytes)
213 safely */
214 strncpy (a, b, MIN (size, MAXSTRLEN - 1));
215 a[MIN (size, MAXSTRLEN - 1)] = '\000';
218 struct ppp_opts *add_opt (struct ppp_opts *option, char *fmt, ...)
220 va_list args;
221 struct ppp_opts *new, *last;
222 new = (struct ppp_opts *) malloc (sizeof (struct ppp_opts));
223 if (!new)
225 l2tp_log (LOG_WARNING,
226 "%s : Unable to allocate ppp option memory. Expect a crash\n",
227 __FUNCTION__);
228 return NULL;
230 new->next = NULL;
231 va_start (args, fmt);
232 vsnprintf (new->option, sizeof (new->option), fmt, args);
233 va_end (args);
234 if (option)
236 last = option;
237 while (last->next)
238 last = last->next;
239 last->next = new;
240 return option;
242 else
243 return new;
245 void opt_destroy (struct ppp_opts *option)
247 struct ppp_opts *tmp;
248 while (option)
250 tmp = option->next;
251 free (option);
252 option = tmp;
256 int get_egd_entropy(char *buf, int count)
258 return -1;
261 int get_sys_entropy(unsigned char *buf, int count)
264 * This way of filling buf with rand() generated data is really
265 * fairly inefficient from a function call point of view...rand()
266 * returns four bytes of data (on most systems, sizeof(int))
267 * and we end up only using 1 byte of it (sizeof(char))...ah
268 * well...it was a *whole* lot easier to code this way...suggestions
269 * for improvements are, of course, welcome
271 int counter;
272 for (counter = 0; counter < count; counter++)
274 buf[counter] = (char)rand();
276 #ifdef DEBUG_ENTROPY
277 bufferDump (buf, count);
278 #endif
279 return count;
282 int get_dev_entropy(unsigned char *buf, int count)
284 int devrandom;
285 ssize_t entropy_amount;
287 devrandom = open ("/dev/urandom", O_RDONLY | O_NONBLOCK);
288 if (devrandom == -1)
290 #ifdef DEBUG_ENTROPY
291 l2tp_log(LOG_WARNING, "%s: couldn't open /dev/urandom,"
292 "falling back to rand()\n",
293 __FUNCTION__);
294 #endif
295 return get_sys_entropy(buf, count);
297 entropy_amount = read(devrandom, buf, count);
298 close(devrandom);
299 return entropy_amount;
302 int get_entropy (unsigned char *buf, int count)
304 if (rand_source == RAND_SYS)
306 return get_sys_entropy(buf, count);
308 else if (rand_source == RAND_DEV)
310 return get_dev_entropy(buf, count);
312 else if (rand_source == RAND_EGD)
314 l2tp_log(LOG_WARNING,
315 "%s: EGD Randomness source not yet implemented\n",
316 __FUNCTION__);
317 return -1;
319 else
321 l2tp_log(LOG_WARNING,
322 "%s: Invalid Randomness source specified (%d)\n",
323 __FUNCTION__, rand_source);
324 return -1;