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).
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 const char *g_LastErrorFilename
;
30 int g_LastErrorLineNumber
;
37 NewlineExists (const char *str
, int len
)
41 const char c
= *str
++;
51 MyDebugInit (unsigned int bufsiz
)
53 NdisZeroMemory (&g_Debug
, sizeof (g_Debug
));
54 g_Debug
.text
= (char *) MemAlloc (bufsiz
, FALSE
);
56 g_Debug
.capacity
= bufsiz
;
63 MemFree (g_Debug
.text
, g_Debug
.capacity
);
64 NdisZeroMemory (&g_Debug
, sizeof (g_Debug
));
68 MyDebugPrint (const unsigned char* format
, ...)
70 if (g_Debug
.text
&& g_Debug
.capacity
> 0 && CAN_WE_PRINT
)
73 ACQUIRE_MUTEX_ADAPTIVE (&g_Debug
.lock
, owned
);
76 const int remaining
= (int)g_Debug
.capacity
- (int)g_Debug
.out
;
84 va_start (args
, format
);
85 status
= RtlStringCchVPrintfExA (g_Debug
.text
+ g_Debug
.out
,
89 STRSAFE_NO_TRUNCATION
| STRSAFE_IGNORE_NULLS
,
94 if (status
== STATUS_SUCCESS
)
95 g_Debug
.out
= (unsigned int) (end
- g_Debug
.text
);
100 g_Debug
.error
= TRUE
;
102 RELEASE_MUTEX (&g_Debug
.lock
);
105 g_Debug
.error
= TRUE
;
110 GetDebugLine (char *buf
, const int len
)
112 static const char *truncated
= "[OUTPUT TRUNCATED]\n";
115 NdisZeroMemory (buf
, len
);
117 if (g_Debug
.text
&& g_Debug
.capacity
> 0)
120 ACQUIRE_MUTEX_ADAPTIVE (&g_Debug
.lock
, owned
);
125 if (g_Debug
.error
|| NewlineExists (g_Debug
.text
+ g_Debug
.in
, (int)g_Debug
.out
- (int)g_Debug
.in
))
127 while (i
< (len
- 1) && g_Debug
.in
< g_Debug
.out
)
129 const char c
= g_Debug
.text
[g_Debug
.in
++];
140 if (g_Debug
.in
== g_Debug
.out
)
142 g_Debug
.in
= g_Debug
.out
= 0;
145 const unsigned int tlen
= strlen (truncated
);
146 if (tlen
< g_Debug
.capacity
)
148 NdisMoveMemory (g_Debug
.text
, truncated
, tlen
+1);
151 g_Debug
.error
= FALSE
;
158 RELEASE_MUTEX (&g_Debug
.lock
);
165 MyAssert (const unsigned char *file
, int line
)
167 DEBUGP (("MYASSERT failed %s/%d\n", file
, line
));
168 KeBugCheckEx (0x0F00BABA,
176 PrMac (const MACADDR mac
)
178 DEBUGP (("%x:%x:%x:%x:%x:%x",
179 mac
[0], mac
[1], mac
[2],
180 mac
[3], mac
[4], mac
[5]));
184 PrIP (IPADDR ip_addr
)
186 const unsigned char *ip
= (const unsigned char *) &ip_addr
;
188 DEBUGP (("%d.%d.%d.%d",
189 ip
[0], ip
[1], ip
[2], ip
[3]));
193 PrIPProto (int proto
)
211 DumpARP (const char *prefix
, const ARP_PACKET
*arp
)
213 DEBUGP (("%s ARP src=", prefix
));
214 PrMac (arp
->m_MAC_Source
);
216 PrMac (arp
->m_MAC_Destination
);
217 DEBUGP ((" OP=0x%04x",
218 (int)ntohs(arp
->m_ARP_Operation
)));
219 DEBUGP ((" M=0x%04x(%d)",
220 (int)ntohs(arp
->m_MAC_AddressType
),
221 (int)arp
->m_MAC_AddressSize
));
222 DEBUGP ((" P=0x%04x(%d)",
223 (int)ntohs(arp
->m_PROTO_AddressType
),
224 (int)arp
->m_PROTO_AddressSize
));
226 DEBUGP ((" MacSrc="));
227 PrMac (arp
->m_ARP_MAC_Source
);
228 DEBUGP ((" MacDest="));
229 PrMac (arp
->m_ARP_MAC_Destination
);
231 DEBUGP ((" IPSrc="));
232 PrIP (arp
->m_ARP_IP_Source
);
233 DEBUGP ((" IPDest="));
234 PrIP (arp
->m_ARP_IP_Destination
);
241 UCHAR payload
[DEFAULT_PACKET_LOOKAHEAD
];
245 DumpPacket2 (const char *prefix
,
246 const ETH_HEADER
*eth
,
247 const unsigned char *data
,
250 struct ethpayload
*ep
= (struct ethpayload
*) MemAlloc (sizeof (struct ethpayload
), TRUE
);
253 if (len
> DEFAULT_PACKET_LOOKAHEAD
)
254 len
= DEFAULT_PACKET_LOOKAHEAD
;
256 NdisMoveMemory (ep
->payload
, data
, len
);
257 DumpPacket (prefix
, (unsigned char *) ep
, sizeof (ETH_HEADER
) + len
);
258 MemFree (ep
, sizeof (struct ethpayload
));
263 DumpPacket (const char *prefix
,
264 const unsigned char *data
,
267 const ETH_HEADER
*eth
= (const ETH_HEADER
*) data
;
268 const IPHDR
*ip
= (const IPHDR
*) (data
+ sizeof (ETH_HEADER
));
270 if (len
< sizeof (ETH_HEADER
))
272 DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix
, len
));
277 if (len
>= sizeof (ARP_PACKET
) && eth
->proto
== htons (ETH_P_ARP
))
279 DumpARP (prefix
, (const ARP_PACKET
*) data
);
284 if (len
>= (sizeof (IPHDR
) + sizeof (ETH_HEADER
))
285 && eth
->proto
== htons (ETH_P_IP
)
286 && IPH_GET_VER (ip
->version_len
) == 4)
288 const int hlen
= IPH_GET_LEN (ip
->version_len
);
289 const int blen
= len
- sizeof (ETH_HEADER
);
292 DEBUGP (("%s IPv4 %s[%d]", prefix
, PrIPProto (ip
->protocol
), len
));
294 if (!(ntohs (ip
->tot_len
) == blen
&& hlen
<= blen
))
301 if (ip
->protocol
== IPPROTO_TCP
302 && blen
- hlen
>= (sizeof (TCPHDR
)))
304 const TCPHDR
*tcp
= (TCPHDR
*) (data
+ sizeof (ETH_HEADER
) + hlen
);
307 DEBUGP ((":%d", ntohs (tcp
->source
)));
310 DEBUGP ((":%d", ntohs (tcp
->dest
)));
315 else if ((ntohs (ip
->frag_off
) & IP_OFFMASK
) == 0
316 && ip
->protocol
== IPPROTO_UDP
317 && blen
- hlen
>= (sizeof (UDPHDR
)))
319 const UDPHDR
*udp
= (UDPHDR
*) (data
+ sizeof (ETH_HEADER
) + hlen
);
322 if ((udp
->dest
== htons (BOOTPC_PORT
) || udp
->dest
== htons (BOOTPS_PORT
))
323 && blen
- hlen
>= (sizeof (UDPHDR
) + sizeof (DHCP
)))
325 const DHCP
*dhcp
= (DHCP
*) (data
327 + sizeof (ETH_HEADER
)
331 - sizeof (ETH_HEADER
)
339 DumpDHCP (eth
, ip
, udp
, dhcp
, optlen
);
347 DEBUGP ((":%d", ntohs (udp
->source
)));
350 DEBUGP ((":%d", ntohs (udp
->dest
)));
357 DEBUGP ((" ipproto=%d ", ip
->protocol
));
368 DEBUGP (("%s ??? src=", prefix
));
372 DEBUGP ((" proto=0x%04x len=%d\n",
373 (int) ntohs(eth
->proto
),