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