2 * Layer Two Tunnelling Protocol Daemon
3 * Copyright (C) 1998 Adtran, Inc.
4 * Copyright (C) 2002 Jeff McAdams
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
17 #include <sys/types.h>
29 #include <netinet/in.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) { \
47 SYSLOG_CALL( openlog (BINARY
, LOG_PID
, LOG_DAEMON
) );
52 void l2tp_log (int level
, const char *fmt
, ...)
57 vsnprintf (buf
, sizeof (buf
), fmt
, args
);
62 SYSLOG_CALL( syslog (level
, "%s", buf
) );
64 fprintf(stderr
, "xl2tpd[%d]: %s", getpid(), buf
);
68 void set_error (struct call
*c
, int error
, const char *fmt
, ...)
73 c
->result
= RESULT_ERROR
;
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;
81 struct buffer
*new_buf (int size
)
83 struct buffer
*b
= malloc (sizeof (struct buffer
));
85 if (!b
|| !size
|| size
< 0)
87 b
->rstart
= malloc (size
);
94 b
->rend
= b
->rstart
+ size
- 1;
100 inline void recycle_buf (struct buffer
*b
)
102 b
->start
= b
->rstart
;
106 #define bufferDumpWIDTH 16
107 void bufferDump (unsigned char *buf
, int buflen
)
110 /* we need TWO characters to DISPLAY ONE byte */
111 char line
[2 * bufferDumpWIDTH
+ 1], *c
;
113 for (i
= 0; i
< buflen
/ bufferDumpWIDTH
; i
++)
116 for (j
= 0; j
< bufferDumpWIDTH
; j
++)
118 sprintf (c
, "%02x", (buf
[i
* bufferDumpWIDTH
+ j
]) & 0xff);
120 c
++; /* again two characters to display ONE byte */
123 l2tp_log (LOG_WARNING
,
124 "%s: buflen=%d, buffer[%d]: *%s*\n", __FUNCTION__
,
129 for (j
= 0; j
< buflen
% bufferDumpWIDTH
; j
++)
132 buf
[(buflen
/ bufferDumpWIDTH
) * bufferDumpWIDTH
+
140 l2tp_log (LOG_WARNING
,
141 "%s: buffer[%d]: *%s*\n", __FUNCTION__
, i
,
146 void do_packet_dump (struct buffer
*buf
)
149 unsigned char *c
= buf
->start
;
150 printf ("packet dump: \nHEX: { ");
151 for (x
= 0; x
< buf
->len
; x
++)
153 printf ("%.2X ", *c
);
156 printf ("}\nASCII: { ");
158 for (x
= 0; x
< buf
->len
; x
++)
160 if (*c
> 31 && *c
< 127)
173 inline void swaps (void *buf_v
, int len
)
176 /* Reverse byte order alpha is little endian so lest save a step.
177 to make things work out easier */
180 unsigned char *tmp
= (_u16
*) buf_v
;
181 for (x
= 0; x
< len
; x
+= 2)
189 /* Reverse byte order (if proper to do so)
190 to make things work out easier */
192 struct hw
{ _u16 s
; } __attribute__ ((packed
)) *p
= (struct hw
*) buf_v
;
193 for (x
= 0; x
< len
/ 2; x
++, p
++)
200 inline void toss (struct buffer
*buf
)
203 * Toss a frame and free up the buffer that contained it
210 inline void safe_copy (char *a
, char *b
, int size
)
212 /* Copies B into A (assuming A holds MAXSTRLEN bytes)
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
, ...)
221 struct ppp_opts
*new, *last
;
222 new = (struct ppp_opts
*) malloc (sizeof (struct ppp_opts
));
225 l2tp_log (LOG_WARNING
,
226 "%s : Unable to allocate ppp option memory. Expect a crash\n",
231 va_start (args
, fmt
);
232 vsnprintf (new->option
, sizeof (new->option
), fmt
, args
);
245 void opt_destroy (struct ppp_opts
*option
)
247 struct ppp_opts
*tmp
;
256 int get_egd_entropy(char *buf
, int count
)
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
272 for (counter
= 0; counter
< count
; counter
++)
274 buf
[counter
] = (char)rand();
277 bufferDump (buf
, count
);
282 int get_dev_entropy(unsigned char *buf
, int count
)
285 ssize_t entropy_amount
;
287 devrandom
= open ("/dev/urandom", O_RDONLY
| O_NONBLOCK
);
291 l2tp_log(LOG_WARNING
, "%s: couldn't open /dev/urandom,"
292 "falling back to rand()\n",
295 return get_sys_entropy(buf
, count
);
297 entropy_amount
= read(devrandom
, buf
, count
);
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",
321 l2tp_log(LOG_WARNING
,
322 "%s: Invalid Randomness source specified (%d)\n",
323 __FUNCTION__
, rand_source
);