2
0

error.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /*
  2. * TAP-Windows -- A kernel driver to provide virtual tap
  3. * device functionality on Windows.
  4. *
  5. * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
  6. *
  7. * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc.,
  8. * and is released under the GPL version 2 (see below).
  9. *
  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.
  13. *
  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.
  18. *
  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
  23. */
  24. //-----------------
  25. // DEBUGGING OUTPUT
  26. //-----------------
  27. const char *g_LastErrorFilename;
  28. int g_LastErrorLineNumber;
  29. #if DBG
  30. DebugOutput g_Debug;
  31. BOOLEAN
  32. NewlineExists (const char *str, int len)
  33. {
  34. while (len-- > 0)
  35. {
  36. const char c = *str++;
  37. if (c == '\n')
  38. return TRUE;
  39. else if (c == '\0')
  40. break;
  41. }
  42. return FALSE;
  43. }
  44. VOID
  45. MyDebugInit (unsigned int bufsiz)
  46. {
  47. NdisZeroMemory (&g_Debug, sizeof (g_Debug));
  48. g_Debug.text = (char *) MemAlloc (bufsiz, FALSE);
  49. if (g_Debug.text)
  50. g_Debug.capacity = bufsiz;
  51. }
  52. VOID
  53. MyDebugFree ()
  54. {
  55. if (g_Debug.text)
  56. MemFree (g_Debug.text, g_Debug.capacity);
  57. NdisZeroMemory (&g_Debug, sizeof (g_Debug));
  58. }
  59. VOID
  60. MyDebugPrint (const unsigned char* format, ...)
  61. {
  62. if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT)
  63. {
  64. BOOLEAN owned;
  65. ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
  66. if (owned)
  67. {
  68. const int remaining = (int)g_Debug.capacity - (int)g_Debug.out;
  69. if (remaining > 0)
  70. {
  71. va_list args;
  72. NTSTATUS status;
  73. char *end;
  74. #ifdef DBG_PRINT
  75. va_start (args, format);
  76. vDbgPrintEx (DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, format, args);
  77. va_end (args);
  78. #endif
  79. va_start (args, format);
  80. status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out,
  81. remaining,
  82. &end,
  83. NULL,
  84. STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS,
  85. format,
  86. args);
  87. va_end (args);
  88. va_start (args, format);
  89. vDbgPrintEx(DPFLTR_IHVDRIVER_ID , 1, format, args);
  90. va_end (args);
  91. if (status == STATUS_SUCCESS)
  92. g_Debug.out = (unsigned int) (end - g_Debug.text);
  93. else
  94. g_Debug.error = TRUE;
  95. }
  96. else
  97. g_Debug.error = TRUE;
  98. RELEASE_MUTEX (&g_Debug.lock);
  99. }
  100. else
  101. g_Debug.error = TRUE;
  102. }
  103. }
  104. BOOLEAN
  105. GetDebugLine (char *buf, const int len)
  106. {
  107. static const char *truncated = "[OUTPUT TRUNCATED]\n";
  108. BOOLEAN ret = FALSE;
  109. NdisZeroMemory (buf, len);
  110. if (g_Debug.text && g_Debug.capacity > 0)
  111. {
  112. BOOLEAN owned;
  113. ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned);
  114. if (owned)
  115. {
  116. int i = 0;
  117. if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in))
  118. {
  119. while (i < (len - 1) && g_Debug.in < g_Debug.out)
  120. {
  121. const char c = g_Debug.text[g_Debug.in++];
  122. if (c == '\n')
  123. break;
  124. buf[i++] = c;
  125. }
  126. if (i < len)
  127. buf[i] = '\0';
  128. }
  129. if (!i)
  130. {
  131. if (g_Debug.in == g_Debug.out)
  132. {
  133. g_Debug.in = g_Debug.out = 0;
  134. if (g_Debug.error)
  135. {
  136. const unsigned int tlen = strlen (truncated);
  137. if (tlen < g_Debug.capacity)
  138. {
  139. NdisMoveMemory (g_Debug.text, truncated, tlen+1);
  140. g_Debug.out = tlen;
  141. }
  142. g_Debug.error = FALSE;
  143. }
  144. }
  145. }
  146. else
  147. ret = TRUE;
  148. RELEASE_MUTEX (&g_Debug.lock);
  149. }
  150. }
  151. return ret;
  152. }
  153. VOID
  154. MyAssert (const unsigned char *file, int line)
  155. {
  156. DEBUGP (("MYASSERT failed %s/%d\n", file, line));
  157. KeBugCheckEx (0x0F00BABA,
  158. (ULONG_PTR) line,
  159. (ULONG_PTR) 0,
  160. (ULONG_PTR) 0,
  161. (ULONG_PTR) 0);
  162. }
  163. VOID
  164. PrMac (const MACADDR mac)
  165. {
  166. DEBUGP (("%x:%x:%x:%x:%x:%x",
  167. mac[0], mac[1], mac[2],
  168. mac[3], mac[4], mac[5]));
  169. }
  170. VOID
  171. PrIP (IPADDR ip_addr)
  172. {
  173. const unsigned char *ip = (const unsigned char *) &ip_addr;
  174. DEBUGP (("%d.%d.%d.%d",
  175. ip[0], ip[1], ip[2], ip[3]));
  176. }
  177. const char *
  178. PrIPProto (int proto)
  179. {
  180. switch (proto)
  181. {
  182. case IPPROTO_UDP:
  183. return "UDP";
  184. case IPPROTO_TCP:
  185. return "TCP";
  186. case IPPROTO_ICMP:
  187. return "ICMP";
  188. case IPPROTO_IGMP:
  189. return "IGMP";
  190. default:
  191. return "???";
  192. }
  193. }
  194. VOID
  195. DumpARP (const char *prefix, const ARP_PACKET *arp)
  196. {
  197. DEBUGP (("%s ARP src=", prefix));
  198. PrMac (arp->m_MAC_Source);
  199. DEBUGP ((" dest="));
  200. PrMac (arp->m_MAC_Destination);
  201. DEBUGP ((" OP=0x%04x",
  202. (int)ntohs(arp->m_ARP_Operation)));
  203. DEBUGP ((" M=0x%04x(%d)",
  204. (int)ntohs(arp->m_MAC_AddressType),
  205. (int)arp->m_MAC_AddressSize));
  206. DEBUGP ((" P=0x%04x(%d)",
  207. (int)ntohs(arp->m_PROTO_AddressType),
  208. (int)arp->m_PROTO_AddressSize));
  209. DEBUGP ((" MacSrc="));
  210. PrMac (arp->m_ARP_MAC_Source);
  211. DEBUGP ((" MacDest="));
  212. PrMac (arp->m_ARP_MAC_Destination);
  213. DEBUGP ((" IPSrc="));
  214. PrIP (arp->m_ARP_IP_Source);
  215. DEBUGP ((" IPDest="));
  216. PrIP (arp->m_ARP_IP_Destination);
  217. DEBUGP (("\n"));
  218. }
  219. struct ethpayload {
  220. ETH_HEADER eth;
  221. UCHAR payload[DEFAULT_PACKET_LOOKAHEAD];
  222. };
  223. VOID
  224. DumpPacket2 (const char *prefix,
  225. const ETH_HEADER *eth,
  226. const unsigned char *data,
  227. unsigned int len)
  228. {
  229. struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE);
  230. if (ep)
  231. {
  232. if (len > DEFAULT_PACKET_LOOKAHEAD)
  233. len = DEFAULT_PACKET_LOOKAHEAD;
  234. ep->eth = *eth;
  235. NdisMoveMemory (ep->payload, data, len);
  236. DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len);
  237. MemFree (ep, sizeof (struct ethpayload));
  238. }
  239. }
  240. VOID
  241. DumpPacket (const char *prefix,
  242. const unsigned char *data,
  243. unsigned int len)
  244. {
  245. const ETH_HEADER *eth = (const ETH_HEADER *) data;
  246. const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER));
  247. if (len < sizeof (ETH_HEADER))
  248. {
  249. DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len));
  250. return;
  251. }
  252. // ARP Packet?
  253. if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP))
  254. {
  255. DumpARP (prefix, (const ARP_PACKET *) data);
  256. return;
  257. }
  258. // IPv4 packet?
  259. if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER))
  260. && eth->proto == htons (ETH_P_IP)
  261. && IPH_GET_VER (ip->version_len) == 4)
  262. {
  263. const int hlen = IPH_GET_LEN (ip->version_len);
  264. const int blen = len - sizeof (ETH_HEADER);
  265. BOOLEAN did = FALSE;
  266. DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len));
  267. if (!(ntohs (ip->tot_len) == blen && hlen <= blen))
  268. {
  269. DEBUGP ((" XXX"));
  270. return;
  271. }
  272. // TCP packet?
  273. if (ip->protocol == IPPROTO_TCP
  274. && blen - hlen >= (sizeof (TCPHDR)))
  275. {
  276. const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen);
  277. DEBUGP ((" "));
  278. PrIP (ip->saddr);
  279. DEBUGP ((":%d", ntohs (tcp->source)));
  280. DEBUGP ((" -> "));
  281. PrIP (ip->daddr);
  282. DEBUGP ((":%d", ntohs (tcp->dest)));
  283. did = TRUE;
  284. }
  285. // UDP packet?
  286. else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0
  287. && ip->protocol == IPPROTO_UDP
  288. && blen - hlen >= (sizeof (UDPHDR)))
  289. {
  290. const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen);
  291. #if 0
  292. // DHCP packet?
  293. if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT))
  294. && blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP)))
  295. {
  296. const DHCP *dhcp = (DHCP *) (data
  297. + hlen
  298. + sizeof (ETH_HEADER)
  299. + sizeof (UDPHDR));
  300. int optlen = len
  301. - sizeof (ETH_HEADER)
  302. - hlen
  303. - sizeof (UDPHDR)
  304. - sizeof (DHCP);
  305. if (optlen < 0)
  306. optlen = 0;
  307. DumpDHCP (eth, ip, udp, dhcp, optlen);
  308. did = TRUE;
  309. }
  310. #endif
  311. if (!did)
  312. {
  313. DEBUGP ((" "));
  314. PrIP (ip->saddr);
  315. DEBUGP ((":%d", ntohs (udp->source)));
  316. DEBUGP ((" -> "));
  317. PrIP (ip->daddr);
  318. DEBUGP ((":%d", ntohs (udp->dest)));
  319. did = TRUE;
  320. }
  321. }
  322. if (!did)
  323. {
  324. DEBUGP ((" ipproto=%d ", ip->protocol));
  325. PrIP (ip->saddr);
  326. DEBUGP ((" -> "));
  327. PrIP (ip->daddr);
  328. }
  329. DEBUGP (("\n"));
  330. return;
  331. }
  332. {
  333. DEBUGP (("%s ??? src=", prefix));
  334. PrMac (eth->src);
  335. DEBUGP ((" dest="));
  336. PrMac (eth->dest);
  337. DEBUGP ((" proto=0x%04x len=%d\n",
  338. (int) ntohs(eth->proto),
  339. len));
  340. }
  341. }
  342. #endif