VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxTAP/error.c@ 10813

Last change on this file since 10813 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1/*
2 * TAP-Win32 -- A kernel driver to provide virtual tap device functionality
3 * on Windows. Originally derived from the CIPE-Win32
4 * project by Damion K. Wilson, with extensive modifications by
5 * James Yonan.
6 *
7 * All source code which derives from the CIPE-Win32 project is
8 * Copyright (C) Damion K. Wilson, 2003, and is released under the
9 * GPL version 2 (see below).
10 *
11 * All other source code is Copyright (C) 2002-2005 OpenVPN Solutions LLC,
12 * and is released under the GPL version 2 (see below).
13 *
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.
17 *
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.
22 *
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
27 */
28
29//-----------------
30// DEBUGGING OUTPUT
31//-----------------
32
33const char *g_LastErrorFilename;
34int g_LastErrorLineNumber;
35
36#if DBG
37
38DebugOutput g_Debug;
39
40BOOLEAN
41NewlineExists (const char *str, int len)
42{
43 while (len-- > 0)
44 {
45 const char c = *str++;
46 if (c == '\n')
47 return TRUE;
48 else if (c == '\0')
49 break;
50 }
51 return FALSE;
52}
53
54VOID
55MyDebugInit (unsigned int bufsiz)
56{
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;
61}
62
63VOID
64MyDebugFree ()
65{
66 if (g_Debug.text)
67 MemFree (g_Debug.text, g_Debug.capacity);
68 NdisZeroMemory (&g_Debug, sizeof (g_Debug));
69}
70
71VOID
72MyDebugPrint (const unsigned char* format, ...)
73{
74 if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT)
75 {
76 BOOLEAN owned;
77 ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
78 if (owned)
79 {
80 const int remaining = (int)g_Debug.capacity - (int)g_Debug.out;
81
82 if (remaining > 0)
83 {
84 va_list args;
85 NTSTATUS status;
86 char *end;
87
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);
97
98 if (status == STATUS_SUCCESS)
99 g_Debug.out = end - g_Debug.text;
100 else
101 g_Debug.error = TRUE;
102 }
103 else
104 g_Debug.error = TRUE;
105
106 RELEASE_MUTEX (&g_Debug.lock);
107 }
108 else
109 g_Debug.error = TRUE;
110 }
111}
112
113BOOLEAN
114GetDebugLine (char *buf, const int len)
115{
116 static const char *truncated = "[OUTPUT TRUNCATED]\n";
117 BOOLEAN ret = FALSE;
118
119 NdisZeroMemory (buf, len);
120
121 if (g_Debug.text && g_Debug.capacity > 0)
122 {
123 BOOLEAN owned;
124 ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
125 if (owned)
126 {
127 int i = 0;
128
129 if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in))
130 {
131 while (i < (len - 1) && g_Debug.in < g_Debug.out)
132 {
133 const char c = g_Debug.text[g_Debug.in++];
134 if (c == '\n')
135 break;
136 buf[i++] = c;
137 }
138 if (i < len)
139 buf[i] = '\0';
140 }
141
142 if (!i)
143 {
144 if (g_Debug.in == g_Debug.out)
145 {
146 g_Debug.in = g_Debug.out = 0;
147 if (g_Debug.error)
148 {
149 const unsigned int tlen = strlen (truncated);
150 if (tlen < g_Debug.capacity)
151 {
152 NdisMoveMemory (g_Debug.text, truncated, tlen+1);
153 g_Debug.out = tlen;
154 }
155 g_Debug.error = FALSE;
156 }
157 }
158 }
159 else
160 ret = TRUE;
161
162 RELEASE_MUTEX (&g_Debug.lock);
163 }
164 }
165 return ret;
166}
167
168VOID
169MyAssert (const unsigned char *file, int line)
170{
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);
177}
178
179VOID
180PrMac (const MACADDR mac)
181{
182 DEBUGP (("%x:%x:%x:%x:%x:%x",
183 mac[0], mac[1], mac[2],
184 mac[3], mac[4], mac[5]));
185}
186
187VOID
188PrIP (IPADDR ip_addr)
189{
190 const unsigned char *ip = (const unsigned char *) &ip_addr;
191
192 DEBUGP (("%d.%d.%d.%d",
193 ip[0], ip[1], ip[2], ip[3]));
194}
195
196const char *
197PrIPProto (int proto)
198{
199 switch (proto)
200 {
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 "???";
211 }
212}
213
214VOID
215DumpARP (const char *prefix, const ARP_PACKET *arp)
216{
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));
229
230 DEBUGP ((" MacSrc="));
231 PrMac (arp->m_ARP_MAC_Source);
232 DEBUGP ((" MacDest="));
233 PrMac (arp->m_ARP_MAC_Destination);
234
235 DEBUGP ((" IPSrc="));
236 PrIP (arp->m_ARP_IP_Source);
237 DEBUGP ((" IPDest="));
238 PrIP (arp->m_ARP_IP_Destination);
239
240 DEBUGP (("\n"));
241}
242
243struct ethpayload {
244 ETH_HEADER eth;
245 UCHAR payload[DEFAULT_PACKET_LOOKAHEAD];
246};
247
248VOID
249DumpPacket2 (const char *prefix,
250 const ETH_HEADER *eth,
251 const unsigned char *data,
252 unsigned int len)
253{
254 struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE);
255 if (ep)
256 {
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));
263 }
264}
265
266VOID
267DumpPacket (const char *prefix,
268 const unsigned char *data,
269 unsigned int len)
270{
271 const ETH_HEADER *eth = (const ETH_HEADER *) data;
272 const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER));
273
274 if (len < sizeof (ETH_HEADER))
275 {
276 DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len));
277 return;
278 }
279
280 // ARP Packet?
281 if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP))
282 {
283 DumpARP (prefix, (const ARP_PACKET *) data);
284 return;
285 }
286
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)
291 {
292 const int hlen = IPH_GET_LEN (ip->version_len);
293 const int blen = len - sizeof (ETH_HEADER);
294 BOOLEAN did = FALSE;
295
296 DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len));
297
298 if (!(ntohs (ip->tot_len) == blen && hlen <= blen))
299 {
300 DEBUGP ((" XXX"));
301 return;
302 }
303
304 // TCP packet?
305 if (ip->protocol == IPPROTO_TCP
306 && blen - hlen >= (sizeof (TCPHDR)))
307 {
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;
316 }
317
318 // UDP packet?
319 else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0
320 && ip->protocol == IPPROTO_UDP
321 && blen - hlen >= (sizeof (UDPHDR)))
322 {
323 const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen);
324
325 // DHCP packet?
326 if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT))
327 && blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP)))
328 {
329 const DHCP *dhcp = (DHCP *) (data
330 + hlen
331 + sizeof (ETH_HEADER)
332 + sizeof (UDPHDR));
333
334 int optlen = len
335 - sizeof (ETH_HEADER)
336 - hlen
337 - sizeof (UDPHDR)
338 - sizeof (DHCP);
339
340 if (optlen < 0)
341 optlen = 0;
342
343 DumpDHCP (eth, ip, udp, dhcp, optlen);
344 did = TRUE;
345 }
346
347 if (!did)
348 {
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;
356 }
357 }
358
359 if (!did)
360 {
361 DEBUGP ((" ipproto=%d ", ip->protocol));
362 PrIP (ip->saddr);
363 DEBUGP ((" -> "));
364 PrIP (ip->daddr);
365 }
366
367 DEBUGP (("\n"));
368 return;
369 }
370
371 {
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));
379 }
380}
381
382#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette