1/***********************************************************************
2*
3* debug.c
4*
5* Debugging routines for L2TP
6*
7* Copyright (C) 2002 by Roaring Penguin Software Inc.
8*
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.
11*
12* LIC: GPL
13*
14***********************************************************************/
15
16static char const RCSID[] =
17"$Id: debug.c 3323 2011-09-21 18:45:48Z lly.dev $";
18
19#include "l2tp.h"
20#include <stdio.h>
21#include <stdarg.h>
22#include <sys/time.h>
23#include <unistd.h>
24#include <syslog.h>
25
26#define AVPCASE(x) case AVP_ ## x: return #x
27#define MSGCASE(x) case MESSAGE_ ## x: return #x
28
29static unsigned long debug_mask = 0;
30
31/* Big bang is when the universe started... set by first call
32   to db */
33static struct timeval big_bang = {0, 0};
34
35/**********************************************************************
36* %FUNCTION: debug_avp_type_to_str
37* %ARGUMENTS:
38*  type -- an AVP type
39* %RETURNS:
40*  A string representation of AVP type
41***********************************************************************/
42char const *
43l2tp_debug_avp_type_to_str(uint16_t type)
44{
45    static char buf[64];
46    switch(type) {
47	AVPCASE(MESSAGE_TYPE);
48	AVPCASE(RESULT_CODE);
49	AVPCASE(PROTOCOL_VERSION);
50	AVPCASE(FRAMING_CAPABILITIES);
51	AVPCASE(BEARER_CAPABILITIES);
52	AVPCASE(TIE_BREAKER);
53	AVPCASE(FIRMWARE_REVISION);
54	AVPCASE(HOST_NAME);
55	AVPCASE(VENDOR_NAME);
56	AVPCASE(ASSIGNED_TUNNEL_ID);
57	AVPCASE(RECEIVE_WINDOW_SIZE);
58	AVPCASE(CHALLENGE);
59	AVPCASE(Q931_CAUSE_CODE);
60	AVPCASE(CHALLENGE_RESPONSE);
61	AVPCASE(ASSIGNED_SESSION_ID);
62	AVPCASE(CALL_SERIAL_NUMBER);
63	AVPCASE(MINIMUM_BPS);
64	AVPCASE(MAXIMUM_BPS);
65	AVPCASE(BEARER_TYPE);
66	AVPCASE(FRAMING_TYPE);
67	AVPCASE(CALLED_NUMBER);
68	AVPCASE(CALLING_NUMBER);
69	AVPCASE(SUB_ADDRESS);
70	AVPCASE(TX_CONNECT_SPEED);
71	AVPCASE(PHYSICAL_CHANNEL_ID);
72	AVPCASE(INITIAL_RECEIVED_CONFREQ);
73	AVPCASE(LAST_SENT_CONFREQ);
74	AVPCASE(LAST_RECEIVED_CONFREQ);
75	AVPCASE(PROXY_AUTHEN_TYPE);
76	AVPCASE(PROXY_AUTHEN_NAME);
77	AVPCASE(PROXY_AUTHEN_CHALLENGE);
78	AVPCASE(PROXY_AUTHEN_ID);
79	AVPCASE(PROXY_AUTHEN_RESPONSE);
80	AVPCASE(CALL_ERRORS);
81	AVPCASE(ACCM);
82	AVPCASE(RANDOM_VECTOR);
83	AVPCASE(PRIVATE_GROUP_ID);
84	AVPCASE(RX_CONNECT_SPEED);
85	AVPCASE(SEQUENCING_REQUIRED);
86    }
87    /* Unknown */
88    sprintf(buf, "Unknown_AVP#%d", (int) type);
89    return buf;
90}
91
92/**********************************************************************
93* %FUNCTION: debug_message_type_to_str
94* %ARGUMENTS:
95*  type -- an MESSAGE type
96* %RETURNS:
97*  A string representation of message type
98***********************************************************************/
99char const *
100l2tp_debug_message_type_to_str(uint16_t type)
101{
102    static char buf[64];
103    switch(type) {
104	MSGCASE(SCCRQ);
105	MSGCASE(SCCRP);
106	MSGCASE(SCCCN);
107	MSGCASE(StopCCN);
108	MSGCASE(HELLO);
109	MSGCASE(OCRQ);
110	MSGCASE(OCRP);
111	MSGCASE(OCCN);
112	MSGCASE(ICRQ);
113	MSGCASE(ICRP);
114	MSGCASE(ICCN);
115	MSGCASE(CDN);
116	MSGCASE(WEN);
117	MSGCASE(SLI);
118	MSGCASE(ZLB);
119    }
120    sprintf(buf, "Unknown_Message#%d", (int) type);
121    return buf;
122}
123
124/**********************************************************************
125* %FUNCTION: debug_tunnel_to_str
126* %ARGUMENTS:
127*  tunnel
128* %RETURNS:
129*  A string representation of tunnel (my_id/assigned_id)
130***********************************************************************/
131char const *
132l2tp_debug_tunnel_to_str(l2tp_tunnel *tunnel)
133{
134    static char buf[64];
135    sprintf(buf, "%d/%d", (int) tunnel->my_id, (int) tunnel->assigned_id);
136    return buf;
137}
138
139/**********************************************************************
140* %FUNCTION: debug_session_to_str
141* %ARGUMENTS:
142*  session
143* %RETURNS:
144*  A string representation of session (my_id/assigned_id)
145***********************************************************************/
146char const *
147l2tp_debug_session_to_str(l2tp_session *session)
148{
149    static char buf[128];
150    sprintf(buf, "(%d/%d, %d/%d)",
151	    (int) session->tunnel->my_id,
152	    (int) session->tunnel->assigned_id,
153	    (int) session->my_id, (int) session->assigned_id);
154    return buf;
155}
156
157/**********************************************************************
158* %FUNCTION: db
159* %ARGUMENTS:
160*  what -- which facet we are debugging
161*  fmt -- printf-style format
162*  args -- arguments
163* %RETURNS:
164*  Nothing
165* %DESCRIPTION:
166*  If bit in debug mask for "what" is set, print debugging message.
167***********************************************************************/
168void
169l2tp_db(int what, char const *fmt, ...)
170{
171    va_list ap;
172    struct timeval now;
173    long sec_diff, usec_diff;
174
175    if (!(debug_mask & what)) return;
176
177    gettimeofday(&now, NULL);
178
179    if (!big_bang.tv_sec) {
180	big_bang = now;
181    }
182
183    /* Compute difference between now and big_bang */
184    sec_diff = now.tv_sec - big_bang.tv_sec;
185    usec_diff = now.tv_usec - big_bang.tv_usec;
186    if (usec_diff < 0) {
187	usec_diff += 1000000;
188	sec_diff--;
189    }
190
191    /* Convert to seconds.milliseconds */
192    usec_diff /= 1000;
193
194    va_start(ap, fmt);
195    fprintf(stderr, "%4ld.%03ld ", sec_diff, usec_diff);
196    vfprintf(stderr, fmt, ap);
197    vsyslog(LOG_DEBUG, fmt, ap);
198    va_end(ap);
199}
200
201/**********************************************************************
202* %FUNCTION: debug_set_bitmask
203* %ARGUMENTS:
204*  mask -- what to set debug bitmask to
205* %RETURNS:
206*  Nothing
207* %DESCRIPTION:
208*  Sets debug bitmask
209***********************************************************************/
210void
211l2tp_debug_set_bitmask(unsigned long mask)
212{
213    debug_mask = mask;
214}
215
216/**********************************************************************
217* %FUNCTION: debug_describe_dgram
218* %ARGUMENTS:
219*  dgram -- an L2TP datagram
220* %RETURNS:
221*  A string describing the datagram
222***********************************************************************/
223char const *
224l2tp_debug_describe_dgram(l2tp_dgram const *dgram)
225{
226    static char buf[256];
227
228    if (dgram->bits & TYPE_BIT) {
229	/* Control datagram */
230	snprintf(buf, sizeof(buf), "type=%s, tid=%d, sid=%d, Nr=%d, Ns=%d",
231		 l2tp_debug_message_type_to_str(dgram->msg_type),
232		 (int) dgram->tid, (int) dgram->sid,
233		 (int) dgram->Nr, (int) dgram->Ns);
234    } else {
235	snprintf(buf, sizeof(buf), "data message tid=%d sid=%d payload_len=%d",
236		 (int) dgram->tid, (int) dgram->sid,
237		 (int) dgram->payload_len);
238    }
239    return buf;
240}
241