Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

881 lines
19 KiB

  1. /*++
  2. Copyright (c) 2001-2002 Microsoft Corporation
  3. Module Name:
  4. teredo.h
  5. Abstract:
  6. This module contains the teredo client and server (cum relay) state.
  7. Author:
  8. Mohit Talwar (mohitt) Mon Oct 22 15:17:48 2001
  9. Environment:
  10. User mode only.
  11. --*/
  12. #ifndef _TEREDO_
  13. #define _TEREDO_
  14. #pragma once
  15. #include <tunuser.h>
  16. #define DEVICE_PREFIX L"\\Device\\"
  17. //
  18. // IP6_HDR
  19. //
  20. // Define the RFC 2292 structure for an IPv6 header.
  21. //
  22. typedef struct _IP6_HDR {
  23. union {
  24. struct ip6_hdrctl {
  25. UINT32 ip6_un1_flow; // 20 bits of flow-ID
  26. UINT16 ip6_un1_plen; // payload length
  27. UINT8 ip6_un1_nxt; // next header
  28. UINT8 ip6_un1_hlim; // hop limit
  29. } ip6_un1;
  30. UINT8 ip6_un2_vfc; // 4 bits version, 4 bits priority
  31. } ip6_ctlun;
  32. IN6_ADDR ip6_src; // source address
  33. IN6_ADDR ip6_dest; // destination address
  34. #define ip6_vfc ip6_ctlun.ip6_un2_vfc
  35. #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
  36. #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
  37. #define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
  38. #define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
  39. #define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
  40. } IP6_HDR, *PIP6_HDR;
  41. #define IPV6_VERSION 0x60 // This is 6 << 4
  42. #define IPV6_TEREDOMTU 1280
  43. #define IPV6_INFINITE_LIFETIME 0xffffffff
  44. #define IPPROTO_NONE 59
  45. //
  46. // HASHTABLE
  47. //
  48. // Define a simple, statically sized, locked hash table.
  49. // Each bucket is a doubly linked LRU list.
  50. //
  51. #define BUCKET_COUNT 29 // # buckets in the hash table
  52. typedef struct _HASHTABLE {
  53. CRITICAL_SECTION Lock; // Protects the table and entries.
  54. ULONG Size; // # entries in the hash table
  55. LIST_ENTRY Bucket[BUCKET_COUNT];
  56. } HASHTABLE, *PHASHTABLE;
  57. //
  58. // TEREDO_TYPE
  59. //
  60. // Define the type of the teredo service.
  61. //
  62. typedef enum {
  63. TEREDO_DEFAULT = 0,
  64. TEREDO_CLIENT,
  65. TEREDO_SERVER,
  66. TEREDO_DISABLED,
  67. TEREDO_AUTOMATIC,
  68. TEREDO_MAXIMUM,
  69. } TEREDO_TYPE, *PTEREDO_TYPE;
  70. //
  71. // TEREDO_PACKET_TYPE
  72. //
  73. // Define the type of a teredo packet.
  74. //
  75. typedef enum {
  76. TEREDO_PACKET_READ, // Data read from TUN device.
  77. TEREDO_PACKET_WRITE, // Data written to TUN device.
  78. TEREDO_PACKET_BUBBLE, // Bubble transmitted on UDP socket.
  79. TEREDO_PACKET_BOUNCE, // Packet bounced on UDP socket.
  80. TEREDO_PACKET_RECEIVE, // Packet received on UDP socket.
  81. TEREDO_PACKET_TRANSMIT, // Packet transmitted on UDP socket.
  82. TEREDO_PACKET_MULTICAST, // Multicast bubble transmitted on UDP socket.
  83. TEREDO_PACKET_MAX,
  84. } TEREDO_PACKET_TYPE, *PTEREDO_PACKET_TYPE;
  85. //
  86. // TEREDO_PACKET
  87. //
  88. // Define a teredo packet.
  89. // The packet structure is followed in memory by the packet's data buffer.
  90. //
  91. typedef struct _TEREDO_PACKET {
  92. #if DBG
  93. ULONG Signature; // TEREDO_PACKET_SIGNATURE
  94. #endif // DBG
  95. OVERLAPPED Overlapped; // For asynchronous completion.
  96. TEREDO_PACKET_TYPE Type; // Packet type.
  97. SOCKADDR_IN SocketAddress; // Peer we are in communication with.
  98. UINT SocketAddressLength; // Length of the peer's socket address.
  99. WSABUF Buffer; // Packet buffer and length.
  100. DWORD Flags; // Flags required during sends and receives.
  101. } TEREDO_PACKET, *PTEREDO_PACKET;
  102. #define TEREDO_PACKET_BUFFER(Packet) \
  103. ((PUCHAR) (((PTEREDO_PACKET) (Packet)) + 1))
  104. typedef
  105. VOID
  106. (TEREDO_REFERENCE)(
  107. VOID
  108. );
  109. typedef TEREDO_REFERENCE *PTEREDO_REFERENCE;
  110. typedef
  111. VOID
  112. (TEREDO_DEREFERENCE)(
  113. VOID
  114. );
  115. typedef TEREDO_DEREFERENCE *PTEREDO_DEREFERENCE;
  116. typedef
  117. VOID
  118. (TEREDO_PACKET_IO_COMPLETE)(
  119. IN DWORD Error,
  120. IN ULONG Bytes,
  121. IN PTEREDO_PACKET Packet
  122. );
  123. typedef TEREDO_PACKET_IO_COMPLETE *PTEREDO_PACKET_IO_COMPLETE;
  124. //
  125. // TEREDO_STATE_TYPE
  126. //
  127. // Define the protocol state values of the teredo client service.
  128. //
  129. typedef enum {
  130. TEREDO_STATE_OFFLINE,
  131. TEREDO_STATE_PROBE,
  132. TEREDO_STATE_QUALIFIED,
  133. TEREDO_STATE_ONLINE,
  134. } TEREDO_STATE_TYPE, *PTEREDO_STATE_TYPE;
  135. //
  136. // TEREDO_IO
  137. //
  138. // Define teredo I/O state.
  139. // NOTE: All addresses and ports are stored in network byte order.
  140. //
  141. typedef struct _TEREDO_IO {
  142. #if DBG
  143. ULONG Signature; // TEREDO_PACKET_SIGNATURE
  144. #endif // DBG
  145. HANDLE PacketHeap; // Head for allocating teredo packets.
  146. ULONG PostedReceives; // Count of posted receives.
  147. HANDLE ReceiveEvent; // Event signalled upon a receive notification.
  148. HANDLE ReceiveEventWait; // Wait registered for ReceiveEvent.
  149. IN_ADDR Group; // Group joined on the native interface.
  150. SOCKADDR_IN ServerAddress; // Teredo server IPv4 address and UDP port.
  151. SOCKADDR_IN SourceAddress; // Preferred source address to teredo server.
  152. SOCKET Socket; // Socket bound to SourceAddress on a UDP port.
  153. HANDLE TunnelDevice; // Interface to the TUNNEL driver.
  154. WCHAR TunnelInterface[MAX_ADAPTER_NAME_LENGTH];
  155. //
  156. // Function handlers.
  157. //
  158. PTEREDO_REFERENCE Reference;
  159. PTEREDO_DEREFERENCE Dereference;
  160. LPOVERLAPPED_COMPLETION_ROUTINE IoCompletionCallback;
  161. } TEREDO_IO, *PTEREDO_IO;
  162. //
  163. // TEREDO_CLIENT_STATE
  164. //
  165. // Define the global state of the teredo client service.
  166. //
  167. // References:
  168. // - One for initialization.
  169. // - One for any running timer.
  170. // - One for each teredo peer.
  171. // - One for each teredo packet
  172. // - One for "the" multicast bubble. At most one outstanding bubble allowed.
  173. // (reads, writes posted on TunDevice & receives, transmits posted on Socket).
  174. //
  175. typedef struct _TEREDO_CLIENT_STATE {
  176. ULONG ReferenceCount; // Number of outstanding references.
  177. TEREDO_IO Io; // I/O state. TUN device and UDP socket.
  178. HANDLE PeerHeap; // Heap for allocating teredo peers.
  179. HANDLE Timer; // One shot timer active in Probe & Qualified.
  180. HANDLE TimerEvent; // Event signalled upon timer deletion.
  181. HANDLE TimerEventWait; // Wait registered for TimerEvent.
  182. BOOL RestartQualifiedTimer; // When NAT mapping is created or refreshed.
  183. LONG Time; // Current time (in seconds).
  184. TEREDO_STATE_TYPE State; // Teredo client service protocol state.
  185. IN6_ADDR Ipv6Prefix; // Teredo IPv6 prefix advertised by server.
  186. ULONG RefreshInterval; // Expected lifetime of client's NAT mapping.
  187. HASHTABLE PeerSet; // Locked set of recent teredo peers.
  188. ULONG BubbleTicks; // "RefreshInterval" ticks until next bubble.
  189. BOOL BubblePosted; // Whether there is any outstanding bubble.
  190. TEREDO_PACKET Packet; // Teredo multicast bubble packet.
  191. IP6_HDR Bubble; // Teredo multicast bubble packet buffer.
  192. } TEREDO_CLIENT_STATE, *PTEREDO_CLIENT_STATE;
  193. //
  194. // TEREDO_SERVER_STATE
  195. //
  196. // Define the global state of the teredo server service.
  197. //
  198. // References:
  199. // - One for initialization.
  200. // - One for each teredo packet
  201. // (reads, writes posted on TunDevice & receives, transmits posted on Socket).
  202. //
  203. typedef struct _TEREDO_SERVER_STATE {
  204. ULONG ReferenceCount; // Number of outstanding references.
  205. TEREDO_IO Io; // I/O state. TUN device and UDP socket.
  206. TEREDO_STATE_TYPE State; // Teredo server service protocol state.
  207. } TEREDO_SERVER_STATE, *PTEREDO_SERVER_STATE;
  208. //
  209. // TEREDO_PEER
  210. //
  211. // Define a teredo peer's state.
  212. //
  213. // References:
  214. // - One for initialization.
  215. // - One for "the" posted bubble. At most one outstanding bubble is allowed.
  216. //
  217. // Synchronization:
  218. // - Link: Protected by PeerSet::Lock.
  219. // - ReferenceCount: InterlockedIncrement, InterlockedDecrement.
  220. // - LastReceive, LastTransmit: Atomic reads and writes.
  221. // - BubbleCount: Single writer! Atomic reads.
  222. // - BubblePosted: InterlockedExchange.
  223. // - Remaining Fields: Read only.
  224. //
  225. typedef struct _TEREDO_PEER {
  226. #if DBG
  227. ULONG Signature; // TEREDO_PEER_SIGNATURE
  228. #endif // DBG
  229. LIST_ENTRY Link; // Linkage within the PeerSet.
  230. ULONG ReferenceCount; // Number of outstanding references.
  231. LONG LastReceive; // Time of last reception from the peer.
  232. LONG LastTransmit; // Time of last transmission to the peer.
  233. IN6_ADDR Address; // Teredo IPv6 address of the peer.
  234. ULONG BubbleCount; // Number of bubbles transmitted to the peer.
  235. BOOL BubblePosted; // Whether there is any outstanding bubble.
  236. TEREDO_PACKET Packet; // Teredo bubble packet.
  237. IP6_HDR Bubble; // Teredo bubble packet buffer.
  238. } TEREDO_PEER, *PTEREDO_PEER;
  239. //
  240. // Cast and Signature Verification
  241. //
  242. #define TEREDO_IO_SIGNATURE 'oIhS' // 'ShIo'
  243. #define TEREDO_PEER_SIGNATURE 'ePhS' // 'ShPe'
  244. #define TEREDO_PACKET_SIGNATURE 'aPhS' // 'ShPa'
  245. //
  246. // A NULL handle is considered a valid structure.
  247. //
  248. #define Cast(Pointer, TYPE) \
  249. ((TYPE *) (Pointer)); \
  250. ASSERT(!(Pointer) || \
  251. (((TYPE *) (Pointer))->Signature == TYPE##_SIGNATURE))
  252. //
  253. // Lower and upper limits on number of posted reads or receives.
  254. //
  255. #define TEREDO_LOW_WATER_MARK 5 // Receives or Reads.
  256. #define TEREDO_HIGH_WATER_MARK 256 // Receives. Reads are fixed.
  257. //
  258. // Intervals used by the protocol.
  259. //
  260. #define INFINITE_INTERVAL 0x7fffffff
  261. #define TEREDO_RESOLVE_INTERVAL 15 * MINUTES
  262. #define TEREDO_PROBE_INTERVAL 15 * SECONDS
  263. #define TEREDO_REFRESH_INTERVAL 30 * SECONDS
  264. #define TEREDO_MULTICAST_BUBBLE_TICKS 0 // In RefreshInterval units.
  265. #define TEREDO_BUBBLE_INTERVAL 10 * SECONDS
  266. #define TEREDO_SLOW_BUBBLE_INTERVAL 5 * MINUTES
  267. #define TEREDO_BUBBLE_THRESHHOLD 2 * MINUTES
  268. #define TEREDO_ROUTER_LIFETIME 5 * HOURS
  269. //
  270. // Teredo multicast bubbles are sent to group 224.0.0.252 on port 337.
  271. //
  272. #define TEREDO_MULTICAST_PREFIX \
  273. { 0x20, 0x03, 0xe0, 0x00, 0x00, 0xfc, 0x01, 0x51, }
  274. #define TEREDO_DEFAULT_TYPE TEREDO_DISABLED
  275. #define TEREDO_PORT htons(337)
  276. #define TEREDO_SERVER_NAME L"teredo.ipv6.microsoft.com"
  277. #define TEREDO_SERVICE_PREFIX { 0x20, 0x03, }
  278. #define KEY_TEREDO_REFRESH_INTERVAL L"RefreshInterval"
  279. #define KEY_TEREDO_TYPE L"Type"
  280. #define KEY_TEREDO_SERVER_NAME L"ServerName"
  281. #define KEY_TEREDO L"System\\CurrentControlSet\\Services\\Teredo"
  282. //
  283. // Configured parameters.
  284. //
  285. extern ULONG TeredoClientRefreshInterval;
  286. extern TEREDO_TYPE TeredoType;
  287. extern WCHAR TeredoServerName[NI_MAXHOST];
  288. extern CONST IN6_ADDR TeredoIpv6ServicePrefix;
  289. extern CONST IN6_ADDR TeredoIpv6MulticastPrefix;
  290. extern TEREDO_CLIENT_STATE TeredoClient;
  291. extern TEREDO_SERVER_STATE TeredoServer;
  292. //
  293. // Time.
  294. //
  295. __inline
  296. LONG
  297. TeredoGetTime(
  298. VOID
  299. )
  300. {
  301. //
  302. // FILETIME is a 64 bit value representing the number of 100 nanoseconds.
  303. //
  304. C_ASSERT(sizeof(FILETIME) == sizeof(ULONGLONG));
  305. ULONGLONG Time;
  306. GetSystemTimeAsFileTime((PFILETIME) &Time);
  307. return ((ULONG) (Time / (10 * 1000 * 1000)));
  308. }
  309. #define TIME_GREATER(a, b) (((a) - (b)) > 0)
  310. //
  311. // Address validation and parsing.
  312. //
  313. __inline
  314. BOOL
  315. IN4_MULTICAST(IN_ADDR a)
  316. {
  317. return ((a.s_addr & 0x0000000f) == 0x0000000e);
  318. }
  319. _inline
  320. BOOL
  321. IN4_ADDR_EQUAL(IN_ADDR a, IN_ADDR b)
  322. {
  323. return (a.s_addr == b.s_addr);
  324. }
  325. _inline
  326. BOOL
  327. IN4_SOCKADDR_EQUAL(CONST SOCKADDR_IN *a, CONST SOCKADDR_IN *b)
  328. {
  329. ASSERT((a->sin_family == AF_INET) && (b->sin_family == AF_INET));
  330. return (IN4_ADDR_EQUAL(a->sin_addr, b->sin_addr) &&
  331. (a->sin_port == b->sin_port));
  332. }
  333. __inline
  334. BOOL
  335. TeredoIpv6GlobalAddress(
  336. IN CONST IN6_ADDR *Address
  337. )
  338. /*++
  339. Routine Description:
  340. Determine whether the supplied IPv6 address is of global unicast scope.
  341. --*/
  342. {
  343. //
  344. // This can be coded quite a bit more efficiently!
  345. //
  346. if (IN6_IS_ADDR_UNSPECIFIED(Address) ||
  347. IN6_IS_ADDR_LOOPBACK(Address) ||
  348. IN6_IS_ADDR_MULTICAST(Address) ||
  349. IN6_IS_ADDR_LINKLOCAL(Address) ||
  350. IN6_IS_ADDR_SITELOCAL(Address)) {
  351. return FALSE;
  352. }
  353. return TRUE;
  354. }
  355. __inline
  356. BOOL
  357. TeredoIpv4GlobalAddress(
  358. IN CONST UCHAR *Address
  359. )
  360. /*++
  361. Routine Description:
  362. Determine whether the supplied IPv4 address is of global unicast scope.
  363. --*/
  364. {
  365. if ((Address[0] > 223) || // ~Unicast
  366. (Address[0] == 0) || // 0/8
  367. (Address[0] == 127) || // 127/8
  368. (Address[0] == 10) || // 10/8
  369. ((Address[0] == 169) && (Address[1] == 254)) || // 169.254/16
  370. ((Address[0] == 172) && ((Address[1] & 0xf0) == 16)) || // 172.16/12
  371. ((Address[0] == 192) && (Address[1] == 168))) { // 192.168/16
  372. return FALSE;
  373. }
  374. return TRUE;
  375. }
  376. __inline
  377. BOOL
  378. TeredoServicePrefix(
  379. IN CONST IN6_ADDR *Address
  380. )
  381. {
  382. return (Address->s6_words[0] == TeredoIpv6ServicePrefix.s6_words[0]);
  383. }
  384. __inline
  385. BOOL
  386. TeredoValidAdvertisedPrefix(
  387. IN CONST IN6_ADDR *Address,
  388. IN UCHAR Length
  389. )
  390. {
  391. if (Length != 64) {
  392. return FALSE;
  393. }
  394. if (!TeredoServicePrefix(Address)) {
  395. return FALSE;
  396. }
  397. if (!TeredoIpv4GlobalAddress((PUCHAR) (Address->s6_words + 1))) {
  398. return FALSE;
  399. }
  400. return TRUE;
  401. }
  402. __inline
  403. VOID
  404. TeredoParseAddress(
  405. IN CONST IN6_ADDR *Address,
  406. OUT PIN_ADDR Ipv4Address,
  407. OUT PUSHORT Ipv4Port
  408. )
  409. {
  410. ASSERT(TeredoServicePrefix(Address));
  411. //
  412. // These are returned in network byte order.
  413. //
  414. ((PUSHORT) Ipv4Address)[0] = Address->s6_words[1];
  415. ((PUSHORT) Ipv4Address)[1] = Address->s6_words[2];
  416. *Ipv4Port = Address->s6_words[3];
  417. }
  418. __inline
  419. BOOL
  420. TeredoEqualPrefix(
  421. IN CONST IN6_ADDR *Address1,
  422. IN CONST IN6_ADDR *Address2
  423. )
  424. {
  425. //
  426. // Compare Teredo IPv6 Service Prefix, Mapped IPv4 Address and Port.
  427. //
  428. return ((Address1->s6_words[0] == Address2->s6_words[0]) &&
  429. (Address1->s6_words[1] == Address2->s6_words[1]) &&
  430. (Address1->s6_words[2] == Address2->s6_words[2]) &&
  431. (Address1->s6_words[3] == Address2->s6_words[3]));
  432. }
  433. //
  434. // Client API
  435. //
  436. DWORD
  437. TeredoInitializeClient(
  438. VOID
  439. );
  440. VOID
  441. TeredoUninitializeClient(
  442. VOID
  443. );
  444. VOID
  445. TeredoCleanupClient(
  446. VOID
  447. );
  448. __inline
  449. VOID
  450. TeredoReferenceClient(
  451. VOID
  452. )
  453. {
  454. ASSERT(TeredoClient.ReferenceCount > 0);
  455. InterlockedIncrement(&(TeredoClient.ReferenceCount));
  456. }
  457. __inline
  458. VOID
  459. TeredoDereferenceClient(
  460. VOID
  461. )
  462. {
  463. ASSERT(TeredoClient.ReferenceCount > 0);
  464. if (InterlockedDecrement(&(TeredoClient.ReferenceCount)) == 0) {
  465. TeredoCleanupClient();
  466. }
  467. }
  468. VOID
  469. TeredoStartClient(
  470. VOID
  471. );
  472. VOID
  473. TeredoStopClient(
  474. VOID
  475. );
  476. VOID
  477. TeredoProbeClient(
  478. VOID
  479. );
  480. VOID
  481. TeredoQualifyClient(
  482. VOID
  483. );
  484. VOID
  485. TeredoClientAddressDeletionNotification(
  486. IN IN_ADDR Address
  487. );
  488. VOID
  489. TeredoClientRefreshIntervalChangeNotification(
  490. VOID
  491. );
  492. __inline
  493. VOID
  494. TeredoRefreshClient(
  495. VOID
  496. )
  497. {
  498. ASSERT(TeredoClient.State != TEREDO_STATE_OFFLINE);
  499. TeredoClientAddressDeletionNotification(
  500. TeredoClient.Io.SourceAddress.sin_addr);
  501. }
  502. //
  503. // Server API
  504. //
  505. DWORD
  506. TeredoInitializeServer(
  507. VOID
  508. );
  509. VOID
  510. TeredoUninitializeServer(
  511. VOID
  512. );
  513. VOID
  514. TeredoCleanupServer(
  515. VOID
  516. );
  517. __inline
  518. VOID
  519. TeredoReferenceServer(
  520. VOID
  521. )
  522. {
  523. ASSERT(TeredoServer.ReferenceCount > 0);
  524. InterlockedIncrement(&(TeredoServer.ReferenceCount));
  525. }
  526. __inline
  527. VOID
  528. TeredoDereferenceServer(
  529. VOID
  530. )
  531. {
  532. ASSERT(TeredoServer.ReferenceCount > 0);
  533. if (InterlockedDecrement(&(TeredoServer.ReferenceCount)) == 0) {
  534. TeredoCleanupServer();
  535. }
  536. }
  537. VOID
  538. TeredoStartServer(
  539. VOID
  540. );
  541. VOID
  542. TeredoStopServer(
  543. VOID
  544. );
  545. VOID
  546. TeredoServerAddressDeletionNotification(
  547. IN IN_ADDR Address
  548. );
  549. __inline
  550. VOID
  551. TeredoRefreshServer(
  552. VOID
  553. )
  554. {
  555. ASSERT(TeredoServer.State != TEREDO_STATE_OFFLINE);
  556. TeredoServerAddressDeletionNotification(
  557. TeredoServer.Io.SourceAddress.sin_addr);
  558. }
  559. //
  560. // Common API
  561. //
  562. BOOL
  563. TeredoInterface(
  564. IN PWCHAR Guid
  565. );
  566. DWORD
  567. TeredoInitializeGlobals(
  568. VOID
  569. );
  570. VOID
  571. TeredoUninitializeGlobals(
  572. VOID
  573. );
  574. VOID
  575. TeredoAddressChangeNotification(
  576. IN BOOL Delete,
  577. IN IN_ADDR Address
  578. );
  579. VOID
  580. TeredoRouteChangeNotification(
  581. VOID
  582. );
  583. VOID
  584. TeredoConfigurationChangeNotification(
  585. VOID
  586. );
  587. VOID
  588. WINAPI
  589. TeredoWmiEventNotification(
  590. IN PWNODE_HEADER Event,
  591. IN UINT_PTR Context
  592. );
  593. VOID
  594. TeredoRequirementChangeNotification(
  595. IN BOOL Required
  596. );
  597. //
  598. // Peer API.
  599. //
  600. DWORD
  601. TeredoInitializePeerSet(
  602. VOID
  603. );
  604. VOID
  605. TeredoUninitializePeerSet(
  606. VOID
  607. );
  608. VOID
  609. TeredoCleanupPeerSet(
  610. VOID
  611. );
  612. PTEREDO_PEER
  613. TeredoFindOrCreatePeer(
  614. IN CONST IN6_ADDR *Address
  615. );
  616. VOID
  617. TeredoDestroyPeer(
  618. IN PTEREDO_PEER Peer
  619. );
  620. __inline
  621. VOID
  622. TeredoReferencePeer(
  623. IN PTEREDO_PEER Peer
  624. )
  625. {
  626. ASSERT(Peer->ReferenceCount > 0);
  627. InterlockedIncrement(&(Peer->ReferenceCount));
  628. }
  629. __inline
  630. VOID
  631. TeredoDereferencePeer(
  632. IN PTEREDO_PEER Peer
  633. )
  634. {
  635. ASSERT(Peer->ReferenceCount > 0);
  636. if (InterlockedDecrement(&(Peer->ReferenceCount)) == 0) {
  637. TeredoDestroyPeer(Peer);
  638. }
  639. }
  640. //
  641. // I/O API.
  642. //
  643. DWORD
  644. TeredoInitializeIo(
  645. IN PTEREDO_IO TeredoIo,
  646. IN IN_ADDR Group,
  647. IN PTEREDO_REFERENCE Reference,
  648. IN PTEREDO_DEREFERENCE Dereference,
  649. IN LPOVERLAPPED_COMPLETION_ROUTINE IoCompletionCallback
  650. );
  651. VOID
  652. TeredoCleanupIo(
  653. IN PTEREDO_IO TeredoIo
  654. );
  655. DWORD
  656. TeredoStartIo(
  657. IN PTEREDO_IO TeredoIo
  658. );
  659. DWORD
  660. TeredoRefreshSocket(
  661. IN PTEREDO_IO TeredoIo
  662. );
  663. VOID
  664. TeredoStopIo(
  665. IN PTEREDO_IO TeredoIo
  666. );
  667. __inline
  668. VOID
  669. TeredoInitializePacket(
  670. IN PTEREDO_PACKET Packet
  671. )
  672. {
  673. #if DBG
  674. Packet->Signature = TEREDO_PACKET_SIGNATURE;
  675. #endif // DBG
  676. ZeroMemory(&(Packet->SocketAddress), sizeof(SOCKADDR_IN));
  677. Packet->SocketAddress.sin_family = AF_INET;
  678. Packet->SocketAddressLength = sizeof(SOCKADDR_IN);
  679. Packet->Flags = 0;
  680. Packet->Buffer.buf = TEREDO_PACKET_BUFFER(Packet);
  681. }
  682. ULONG
  683. TeredoPostReceives(
  684. IN PTEREDO_IO TeredoIo,
  685. IN PTEREDO_PACKET Packet
  686. );
  687. PTEREDO_PACKET
  688. TeredoTransmitPacket(
  689. IN PTEREDO_IO TeredoIo,
  690. IN PTEREDO_PACKET Packet
  691. );
  692. BOOL
  693. TeredoPostRead(
  694. IN PTEREDO_IO TeredoIo,
  695. IN PTEREDO_PACKET Packet OPTIONAL
  696. );
  697. PTEREDO_PACKET
  698. TeredoWritePacket(
  699. IN PTEREDO_IO TeredoIo,
  700. IN PTEREDO_PACKET Packet
  701. );
  702. //
  703. // Utility Functions.
  704. //
  705. ICMPv6Header *
  706. TeredoParseIpv6Headers(
  707. IN PUCHAR Buffer,
  708. IN ULONG Bytes
  709. );
  710. #endif // _TEREDO_