Upgrade to OpenVPN 2.1.0
[tomato.git] / release / src / router / openvpn / tap-win32 / tmp / error.c
blobdd27024e837267fc6901765d6e4162e00ef2f2de
1 /*
2 * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap
3 * device functionality on Windows.
5 * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
7 * This source code is Copyright (C) 2002-2009 OpenVPN Technologies, Inc.,
8 * and is released under the GPL version 2 (see below), however due
9 * to the extra costs of supporting Windows Vista, OpenVPN Solutions
10 * LLC reserves the right to change the terms of the TAP-Win32/TAP-Win64
11 * license for versions 9.1 and higher prior to the official release of
12 * OpenVPN 2.1.
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2
16 * as published by the Free Software Foundation.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program (see the file COPYING included with this
25 * distribution); if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 //-----------------
30 // DEBUGGING OUTPUT
31 //-----------------
33 const char *g_LastErrorFilename;
34 int g_LastErrorLineNumber;
36 #if DBG
38 DebugOutput g_Debug;
40 BOOLEAN
41 NewlineExists (const char *str, int len)
43 while (len-- > 0)
45 const char c = *str++;
46 if (c == '\n')
47 return TRUE;
48 else if (c == '\0')
49 break;
51 return FALSE;
54 VOID
55 MyDebugInit (unsigned int bufsiz)
57 NdisZeroMemory (&g_Debug, sizeof (g_Debug));
58 g_Debug.text = (char *) MemAlloc (bufsiz, FALSE);
59 if (g_Debug.text)
60 g_Debug.capacity = bufsiz;
63 VOID
64 MyDebugFree ()
66 if (g_Debug.text)
67 MemFree (g_Debug.text, g_Debug.capacity);
68 NdisZeroMemory (&g_Debug, sizeof (g_Debug));
71 VOID
72 MyDebugPrint (const unsigned char* format, ...)
74 if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT)
76 BOOLEAN owned;
77 ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
78 if (owned)
80 const int remaining = (int)g_Debug.capacity - (int)g_Debug.out;
82 if (remaining > 0)
84 va_list args;
85 NTSTATUS status;
86 char *end;
88 va_start (args, format);
89 status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out,
90 remaining,
91 &end,
92 NULL,
93 STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS,
94 format,
95 args);
96 va_end (args);
98 if (status == STATUS_SUCCESS)
99 g_Debug.out = (unsigned int) (end - g_Debug.text);
100 else
101 g_Debug.error = TRUE;
103 else
104 g_Debug.error = TRUE;
106 RELEASE_MUTEX (&g_Debug.lock);
108 else
109 g_Debug.error = TRUE;
113 BOOLEAN
114 GetDebugLine (char *buf, const int len)
116 static const char *truncated = "[OUTPUT TRUNCATED]\n";
117 BOOLEAN ret = FALSE;
119 NdisZeroMemory (buf, len);
121 if (g_Debug.text && g_Debug.capacity > 0)
123 BOOLEAN owned;
124 ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
125 if (owned)
127 int i = 0;
129 if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in))
131 while (i < (len - 1) && g_Debug.in < g_Debug.out)
133 const char c = g_Debug.text[g_Debug.in++];
134 if (c == '\n')
135 break;
136 buf[i++] = c;
138 if (i < len)
139 buf[i] = '\0';
142 if (!i)
144 if (g_Debug.in == g_Debug.out)
146 g_Debug.in = g_Debug.out = 0;
147 if (g_Debug.error)
149 const unsigned int tlen = strlen (truncated);
150 if (tlen < g_Debug.capacity)
152 NdisMoveMemory (g_Debug.text, truncated, tlen+1);
153 g_Debug.out = tlen;
155 g_Debug.error = FALSE;
159 else
160 ret = TRUE;
162 RELEASE_MUTEX (&g_Debug.lock);
165 return ret;
168 VOID
169 MyAssert (const unsigned char *file, int line)
171 DEBUGP (("MYASSERT failed %s/%d\n", file, line));
172 KeBugCheckEx (0x0F00BABA,
173 (ULONG_PTR) line,
174 (ULONG_PTR) 0,
175 (ULONG_PTR) 0,
176 (ULONG_PTR) 0);
179 VOID
180 PrMac (const MACADDR mac)
182 DEBUGP (("%x:%x:%x:%x:%x:%x",
183 mac[0], mac[1], mac[2],
184 mac[3], mac[4], mac[5]));
187 VOID
188 PrIP (IPADDR ip_addr)
190 const unsigned char *ip = (const unsigned char *) &ip_addr;
192 DEBUGP (("%d.%d.%d.%d",
193 ip[0], ip[1], ip[2], ip[3]));
196 const char *
197 PrIPProto (int proto)
199 switch (proto)
201 case IPPROTO_UDP:
202 return "UDP";
203 case IPPROTO_TCP:
204 return "TCP";
205 case IPPROTO_ICMP:
206 return "ICMP";
207 case IPPROTO_IGMP:
208 return "IGMP";
209 default:
210 return "???";
214 VOID
215 DumpARP (const char *prefix, const ARP_PACKET *arp)
217 DEBUGP (("%s ARP src=", prefix));
218 PrMac (arp->m_MAC_Source);
219 DEBUGP ((" dest="));
220 PrMac (arp->m_MAC_Destination);
221 DEBUGP ((" OP=0x%04x",
222 (int)ntohs(arp->m_ARP_Operation)));
223 DEBUGP ((" M=0x%04x(%d)",
224 (int)ntohs(arp->m_MAC_AddressType),
225 (int)arp->m_MAC_AddressSize));
226 DEBUGP ((" P=0x%04x(%d)",
227 (int)ntohs(arp->m_PROTO_AddressType),
228 (int)arp->m_PROTO_AddressSize));
230 DEBUGP ((" MacSrc="));
231 PrMac (arp->m_ARP_MAC_Source);
232 DEBUGP ((" MacDest="));
233 PrMac (arp->m_ARP_MAC_Destination);
235 DEBUGP ((" IPSrc="));
236 PrIP (arp->m_ARP_IP_Source);
237 DEBUGP ((" IPDest="));
238 PrIP (arp->m_ARP_IP_Destination);
240 DEBUGP (("\n"));
243 struct ethpayload {
244 ETH_HEADER eth;
245 UCHAR payload[DEFAULT_PACKET_LOOKAHEAD];
248 VOID
249 DumpPacket2 (const char *prefix,
250 const ETH_HEADER *eth,
251 const unsigned char *data,
252 unsigned int len)
254 struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE);
255 if (ep)
257 if (len > DEFAULT_PACKET_LOOKAHEAD)
258 len = DEFAULT_PACKET_LOOKAHEAD;
259 ep->eth = *eth;
260 NdisMoveMemory (ep->payload, data, len);
261 DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len);
262 MemFree (ep, sizeof (struct ethpayload));
266 VOID
267 DumpPacket (const char *prefix,
268 const unsigned char *data,
269 unsigned int len)
271 const ETH_HEADER *eth = (const ETH_HEADER *) data;
272 const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER));
274 if (len < sizeof (ETH_HEADER))
276 DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len));
277 return;
280 // ARP Packet?
281 if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP))
283 DumpARP (prefix, (const ARP_PACKET *) data);
284 return;
287 // IPv4 packet?
288 if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER))
289 && eth->proto == htons (ETH_P_IP)
290 && IPH_GET_VER (ip->version_len) == 4)
292 const int hlen = IPH_GET_LEN (ip->version_len);
293 const int blen = len - sizeof (ETH_HEADER);
294 BOOLEAN did = FALSE;
296 DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len));
298 if (!(ntohs (ip->tot_len) == blen && hlen <= blen))
300 DEBUGP ((" XXX"));
301 return;
304 // TCP packet?
305 if (ip->protocol == IPPROTO_TCP
306 && blen - hlen >= (sizeof (TCPHDR)))
308 const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen);
309 DEBUGP ((" "));
310 PrIP (ip->saddr);
311 DEBUGP ((":%d", ntohs (tcp->source)));
312 DEBUGP ((" -> "));
313 PrIP (ip->daddr);
314 DEBUGP ((":%d", ntohs (tcp->dest)));
315 did = TRUE;
318 // UDP packet?
319 else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0
320 && ip->protocol == IPPROTO_UDP
321 && blen - hlen >= (sizeof (UDPHDR)))
323 const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen);
325 // DHCP packet?
326 if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT))
327 && blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP)))
329 const DHCP *dhcp = (DHCP *) (data
330 + hlen
331 + sizeof (ETH_HEADER)
332 + sizeof (UDPHDR));
334 int optlen = len
335 - sizeof (ETH_HEADER)
336 - hlen
337 - sizeof (UDPHDR)
338 - sizeof (DHCP);
340 if (optlen < 0)
341 optlen = 0;
343 DumpDHCP (eth, ip, udp, dhcp, optlen);
344 did = TRUE;
347 if (!did)
349 DEBUGP ((" "));
350 PrIP (ip->saddr);
351 DEBUGP ((":%d", ntohs (udp->source)));
352 DEBUGP ((" -> "));
353 PrIP (ip->daddr);
354 DEBUGP ((":%d", ntohs (udp->dest)));
355 did = TRUE;
359 if (!did)
361 DEBUGP ((" ipproto=%d ", ip->protocol));
362 PrIP (ip->saddr);
363 DEBUGP ((" -> "));
364 PrIP (ip->daddr);
367 DEBUGP (("\n"));
368 return;
372 DEBUGP (("%s ??? src=", prefix));
373 PrMac (eth->src);
374 DEBUGP ((" dest="));
375 PrMac (eth->dest);
376 DEBUGP ((" proto=0x%04x len=%d\n",
377 (int) ntohs(eth->proto),
378 len));
382 #endif