123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- /*
- * TAP-Windows -- A kernel driver to provide virtual tap
- * device functionality on Windows.
- *
- * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
- *
- * This source code is Copyright (C) 2002-2014 OpenVPN Technologies, Inc.,
- * and is released under the GPL version 2 (see below).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #include "tap.h"
- //-----------------
- // DEBUGGING OUTPUT
- //-----------------
- const char *g_LastErrorFilename;
- int g_LastErrorLineNumber;
- #if DBG
- DebugOutput g_Debug;
- BOOLEAN
- NewlineExists (const char *str, int len)
- {
- while (len-- > 0)
- {
- const char c = *str++;
- if (c == '\n')
- return TRUE;
- else if (c == '\0')
- break;
- }
- return FALSE;
- }
- VOID
- MyDebugInit (unsigned int bufsiz)
- {
- NdisZeroMemory (&g_Debug, sizeof (g_Debug));
- g_Debug.text = (char *) MemAlloc (bufsiz, FALSE);
- if (g_Debug.text)
- {
- g_Debug.capacity = bufsiz;
- }
- }
- VOID
- MyDebugFree ()
- {
- if (g_Debug.text)
- {
- MemFree (g_Debug.text, g_Debug.capacity);
- }
- NdisZeroMemory (&g_Debug, sizeof (g_Debug));
- }
- VOID
- MyDebugPrint (const unsigned char* format, ...)
- {
- if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT)
- {
- BOOLEAN owned;
- ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
- if (owned)
- {
- const int remaining = (int)g_Debug.capacity - (int)g_Debug.out;
- if (remaining > 0)
- {
- va_list args;
- NTSTATUS status;
- char *end;
- #ifdef DBG_PRINT
- va_start (args, format);
- vDbgPrintEx (DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, format, args);
- va_end (args);
- #endif
- va_start (args, format);
- status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out,
- remaining,
- &end,
- NULL,
- STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS,
- format,
- args);
- va_end (args);
- va_start (args, format);
- vDbgPrintEx(DPFLTR_IHVDRIVER_ID , 1, format, args);
- va_end (args);
- if (status == STATUS_SUCCESS)
- g_Debug.out = (unsigned int) (end - g_Debug.text);
- else
- g_Debug.error = TRUE;
- }
- else
- g_Debug.error = TRUE;
- RELEASE_MUTEX (&g_Debug.lock);
- }
- else
- g_Debug.error = TRUE;
- }
- }
- BOOLEAN
- GetDebugLine (
- __in char *buf,
- __in const int len
- )
- {
- static const char *truncated = "[OUTPUT TRUNCATED]\n";
- BOOLEAN ret = FALSE;
- NdisZeroMemory (buf, len);
- if (g_Debug.text && g_Debug.capacity > 0)
- {
- BOOLEAN owned;
- ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
- if (owned)
- {
- int i = 0;
- if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in))
- {
- while (i < (len - 1) && g_Debug.in < g_Debug.out)
- {
- const char c = g_Debug.text[g_Debug.in++];
- if (c == '\n')
- break;
- buf[i++] = c;
- }
- if (i < len)
- buf[i] = '\0';
- }
- if (!i)
- {
- if (g_Debug.in == g_Debug.out)
- {
- g_Debug.in = g_Debug.out = 0;
- if (g_Debug.error)
- {
- const unsigned int tlen = strlen (truncated);
- if (tlen < g_Debug.capacity)
- {
- NdisMoveMemory (g_Debug.text, truncated, tlen+1);
- g_Debug.out = tlen;
- }
- g_Debug.error = FALSE;
- }
- }
- }
- else
- ret = TRUE;
- RELEASE_MUTEX (&g_Debug.lock);
- }
- }
- return ret;
- }
- VOID
- PrMac (const MACADDR mac)
- {
- DEBUGP (("%x:%x:%x:%x:%x:%x",
- mac[0], mac[1], mac[2],
- mac[3], mac[4], mac[5]));
- }
- VOID
- PrIP (IPADDR ip_addr)
- {
- const unsigned char *ip = (const unsigned char *) &ip_addr;
- DEBUGP (("%d.%d.%d.%d",
- ip[0], ip[1], ip[2], ip[3]));
- }
- const char *
- PrIPProto (int proto)
- {
- switch (proto)
- {
- case IPPROTO_UDP:
- return "UDP";
- case IPPROTO_TCP:
- return "TCP";
- case IPPROTO_ICMP:
- return "ICMP";
- case IPPROTO_IGMP:
- return "IGMP";
- default:
- return "???";
- }
- }
- VOID
- DumpARP (const char *prefix, const ARP_PACKET *arp)
- {
- DEBUGP (("%s ARP src=", prefix));
- PrMac (arp->m_MAC_Source);
- DEBUGP ((" dest="));
- PrMac (arp->m_MAC_Destination);
- DEBUGP ((" OP=0x%04x",
- (int)ntohs(arp->m_ARP_Operation)));
- DEBUGP ((" M=0x%04x(%d)",
- (int)ntohs(arp->m_MAC_AddressType),
- (int)arp->m_MAC_AddressSize));
- DEBUGP ((" P=0x%04x(%d)",
- (int)ntohs(arp->m_PROTO_AddressType),
- (int)arp->m_PROTO_AddressSize));
- DEBUGP ((" MacSrc="));
- PrMac (arp->m_ARP_MAC_Source);
- DEBUGP ((" MacDest="));
- PrMac (arp->m_ARP_MAC_Destination);
- DEBUGP ((" IPSrc="));
- PrIP (arp->m_ARP_IP_Source);
- DEBUGP ((" IPDest="));
- PrIP (arp->m_ARP_IP_Destination);
- DEBUGP (("\n"));
- }
- struct ethpayload
- {
- ETH_HEADER eth;
- UCHAR payload[DEFAULT_PACKET_LOOKAHEAD];
- };
- #ifdef ALLOW_PACKET_DUMP
- VOID
- DumpPacket2(
- __in const char *prefix,
- __in const ETH_HEADER *eth,
- __in const unsigned char *data,
- __in unsigned int len
- )
- {
- struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE);
- if (ep)
- {
- if (len > DEFAULT_PACKET_LOOKAHEAD)
- len = DEFAULT_PACKET_LOOKAHEAD;
- ep->eth = *eth;
- NdisMoveMemory (ep->payload, data, len);
- DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len);
- MemFree (ep, sizeof (struct ethpayload));
- }
- }
- VOID
- DumpPacket(
- __in const char *prefix,
- __in const unsigned char *data,
- __in unsigned int len
- )
- {
- const ETH_HEADER *eth = (const ETH_HEADER *) data;
- const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER));
- if (len < sizeof (ETH_HEADER))
- {
- DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len));
- return;
- }
- // ARP Packet?
- if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP))
- {
- DumpARP (prefix, (const ARP_PACKET *) data);
- return;
- }
- // IPv4 packet?
- if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER))
- && eth->proto == htons (ETH_P_IP)
- && IPH_GET_VER (ip->version_len) == 4)
- {
- const int hlen = IPH_GET_LEN (ip->version_len);
- const int blen = len - sizeof (ETH_HEADER);
- BOOLEAN did = FALSE;
- DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len));
- if (!(ntohs (ip->tot_len) == blen && hlen <= blen))
- {
- DEBUGP ((" XXX"));
- return;
- }
- // TCP packet?
- if (ip->protocol == IPPROTO_TCP
- && blen - hlen >= (sizeof (TCPHDR)))
- {
- const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen);
- DEBUGP ((" "));
- PrIP (ip->saddr);
- DEBUGP ((":%d", ntohs (tcp->source)));
- DEBUGP ((" -> "));
- PrIP (ip->daddr);
- DEBUGP ((":%d", ntohs (tcp->dest)));
- did = TRUE;
- }
- // UDP packet?
- else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0
- && ip->protocol == IPPROTO_UDP
- && blen - hlen >= (sizeof (UDPHDR)))
- {
- const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen);
- // DHCP packet?
- if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT))
- && blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP)))
- {
- const DHCP *dhcp = (DHCP *) (data
- + hlen
- + sizeof (ETH_HEADER)
- + sizeof (UDPHDR));
- int optlen = len
- - sizeof (ETH_HEADER)
- - hlen
- - sizeof (UDPHDR)
- - sizeof (DHCP);
- if (optlen < 0)
- optlen = 0;
- DumpDHCP (eth, ip, udp, dhcp, optlen);
- did = TRUE;
- }
- if (!did)
- {
- DEBUGP ((" "));
- PrIP (ip->saddr);
- DEBUGP ((":%d", ntohs (udp->source)));
- DEBUGP ((" -> "));
- PrIP (ip->daddr);
- DEBUGP ((":%d", ntohs (udp->dest)));
- did = TRUE;
- }
- }
- if (!did)
- {
- DEBUGP ((" ipproto=%d ", ip->protocol));
- PrIP (ip->saddr);
- DEBUGP ((" -> "));
- PrIP (ip->daddr);
- }
- DEBUGP (("\n"));
- return;
- }
- {
- DEBUGP (("%s ??? src=", prefix));
- PrMac (eth->src);
- DEBUGP ((" dest="));
- PrMac (eth->dest);
- DEBUGP ((" proto=0x%04x len=%d\n",
- (int) ntohs(eth->proto),
- len));
- }
- }
- #endif // ALLOW_PACKET_DUMP
- #endif
|