1    | /*
2    |  * Layer Two Tunnelling Protocol Daemon
3    |  * Copyright (C) 1998 Adtran, Inc.
4    |  *
5    |  * Mark Spencer
6    |  *
7    |  * This software is distributed under the terms
8    |  * of the GPL, which you should have received
9    |  * along with this source.
10   |  *
11   |  * Miscellaneous but important functions
12   |  *
13   |  */
14   | #include <stdarg.h>
15   | #include <stdio.h>
16   | #include <stdlib.h>
17   | #include <errno.h>
18   | #include <string.h>
19   | #include <syslog.h>
20   | #if defined(SOLARIS)
21   | # include <varargs.h>
22   | #endif
23   | #include <netinet/in.h>
24   | #include "l2tp.h"
25   | 
26   | void log (int level, const char *fmt, ...)
27   | {
28   |     char buf[256];
29   |     va_list args;
30   |     va_start (args, fmt);
31   |     vsnprintf (buf, sizeof (buf), fmt, args);
32   |     va_end (args);		//bk - otherwise ppc segfaults
33   |     va_start (args, fmt);	//bk
34   |     vfprintf (stderr, fmt, args);
35   |     fflush (stderr);
36   |     openlog (BINARY, LOG_PID, LOG_DAEMON);
37   |     syslog (level, "%s", buf);
38   |     va_end (args);
39   | }
40   | 
41   | void set_error (struct call *c, int error, const char *fmt, ...)
42   | {
43   |     va_list args;
44   |     va_start (args, fmt);
45   |     c->error = error;
46   |     c->result = RESULT_ERROR;
47   |     c->needclose = -1;
48   |     vsnprintf (c->errormsg, sizeof (c->errormsg), fmt, args);
49   |     if (c->errormsg[strlen (c->errormsg) - 1] == '\n')
50   | 	c->errormsg[strlen (c->errormsg) - 1] = 0;
51   |     va_end (args);
52   | }
53   | 
54   | struct buffer *new_buf (int size)
55   | {
56   |     struct buffer *b = malloc (sizeof (struct buffer));
57   |     if (!b || !size || size < 0)
58   | 	return NULL;
59   |     b->rstart = malloc (size);
60   |     if (!b->rstart)
61   |     {
62   | 	free (b);
63   | 	return NULL;
64   |     }
65   |     b->start = b->rstart;
66   |     b->rend = b->rstart + size - 1;
67   |     b->len = size;
68   |     b->maxlen = size;
69   |     return b;
70   | }
71   | 
72   | inline void recycle_buf (struct buffer *b)
73   | {
74   |     b->start = b->rstart;
75   |     b->len = b->maxlen;
76   | }
77   | 
78   | #define bufferDumpWIDTH 16
79   | void bufferDump (buf, buflen)
80   |      char *buf;
81   |      int buflen;
82   | {
83   |     int i = 0, j = 0;
84   |     unsigned char line[2 * bufferDumpWIDTH + 1], *c;	/* we need TWO characters to DISPLAY ONE byte */
85   | 
86   |     for (i = 0; i < buflen / bufferDumpWIDTH; i++)
87   |     {
88   | 	c = line;
89   | 	for (j = 0; j < bufferDumpWIDTH; j++)
90   | 	{
91   | 	    sprintf (c, "%02x ", (buf[i * bufferDumpWIDTH + j]) & 0xff);
92   | 	    c++;
93   | 	    c++;		/* again two characters to display ONE byte */
94   | 	}
95   | 	*c = '\0';
96   | 	log (LOG_WARN, "%s: buflen=%d, buffer[%d]: *%s*\n", __FUNCTION__,
97   | 	     buflen, i, line);
98   |     }
99   | 
100  |     c = line;
101  |     for (j = 0; j < buflen % bufferDumpWIDTH; j++)
102  |     {
103  | 	sprintf (c, "%02x ",
104  | 		 buf[(buflen / bufferDumpWIDTH) * bufferDumpWIDTH +
105  | 		     j] & 0xff);
106  | 	c++;
107  | 	c++;
108  |     }
109  |     if (c != line)
110  |     {
111  | 	*c = '\0';
112  | 	log (LOG_WARN, "%s:             buffer[%d]: *%s*\n", __FUNCTION__, i,
113  | 	     line);
114  |     }
115  | }
116  | 
117  | void do_packet_dump (struct buffer *buf)
118  | {
119  |     int x;
120  |     unsigned char *c = buf->start;
121  |     printf ("packet dump: \nHEX: { ");
122  |     for (x = 0; x < buf->len; x++)
123  |     {
124  | 	printf ("%.2X ", *c);
125  | 	c++;
126  |     };
127  |     printf ("}\nASCII: { ");
128  |     c = buf->start;
129  |     for (x = 0; x < buf->len; x++)
130  |     {
131  | 	if (*c > 31 && *c < 127)
132  | 	{
133  | 	    putchar (*c);
134  | 	}
135  | 	else
136  | 	{
137  | 	    putchar (' ');
138  | 	}
139  | 	c++;
140  |     }
141  |     printf ("}\n");
142  | }
143  | 
144  | inline void swaps (void *buf_v, int len)
145  | {
146  | #ifdef __alpha
147  |     /* Reverse byte order alpha is little endian so lest save a step.
148  |        to make things work out easier */
149  |     int x;
150  |     unsigned char t1;
151  |     unsigned char *tmp = (_u16 *) buf_v;
152  |     for (x = 0; x < len; x += 2)
153  |     {
154  | 	t1 = tmp[x];
155  | 	tmp[x] = tmp[x + 1];
156  | 	tmp[x + 1] = t1;
157  |     }
158  | #else
159  | 
160  |     /* Reverse byte order (if proper to do so) 
161  |        to make things work out easier */
162  |     int x;
163  |     _u16 *tmp = (_u16 *) buf_v;
164  |     for (x = 0; x < len / 2; x++)
165  | 	tmp[x] = ntohs (tmp[x]);
166  | #endif
167  | }
168  | 
169  | 
170  | 
171  | inline void toss (struct buffer *buf)
172  | {
173  |     /*
174  |      * Toss a frame and free up the buffer that contained it
175  |      */
176  | 
177  |     free (buf->rstart);
178  |     free (buf);
179  | }
180  | 
181  | inline void safe_copy (char *a, char *b, int size)
182  | {
183  |     /* Copies B into A (assuming A holds MAXSTRLEN bytes)
184  |        safely */
185  |     strncpy (a, b, MIN (size, MAXSTRLEN - 1));
186  |     a[MIN (size, MAXSTRLEN - 1)] = '\000';
187  | }
188  | 
189  | struct ppp_opts *add_opt (struct ppp_opts *option, char *fmt, ...)
190  | {
191  |     va_list args;
192  |     struct ppp_opts *new, *last;
193  |     new = (struct ppp_opts *) malloc (sizeof (struct ppp_opts));
194  |     if (!new)
195  |     {
196  | 	log (LOG_WARN,
197  | 	     "%s : Unable to allocate ppp option memory.  Expect a crash\n",
198  | 	     __FUNCTION__);
199  | 	return NULL;
200  |     }
201  |     new->next = NULL;
202  |     va_start (args, fmt);
203  |     vsnprintf (new->option, sizeof (new->option), fmt, args);
204  |     va_end (args);
205  |     if (option)
206  |     {
207  | 	last = option;
208  | 	while (last->next)
209  | 	    last = last->next;
210  | 	last->next = new;
211  | 	return option;
212  |     }
213  |     else
214  | 	return new;
215  | }
216  | void opt_destroy (struct ppp_opts *option)
217  | {
218  |     struct ppp_opts *tmp;
219  |     while (option)
220  |     {
221  | 	tmp = option->next;
222  | 	free (option);
223  | 	option = tmp;
224  |     };
225  | }