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.

3515 lines
131 KiB

  1. /*++
  2. Copyright (c) 1990-2000 Microsoft Corporation
  3. Module Name:
  4. iprcv.c - IP receive routines.
  5. Abstract:
  6. This module contains all receive related IP routines.
  7. Author:
  8. [Environment:]
  9. kernel mode only
  10. [Notes:]
  11. optional-notes
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #include "ip.h"
  16. #include "info.h"
  17. #include "iproute.h"
  18. #include "arpdef.h"
  19. #include "iprtdef.h"
  20. #include "igmp.h"
  21. #if IPMCAST
  22. void IPMForwardAfterTD(NetTableEntry *pPrimarySrcNte, PNDIS_PACKET pnpPacket,
  23. UINT uiBytesCopied);
  24. #endif
  25. // Following is to prevent ip fragment attack
  26. uint MaxRH = 100; // maximum number of reassembly headers allowed
  27. uint NumRH = 0; // Count of RH in use
  28. uint MaxOverlap = 5; // maximum number overlaps allowed for one
  29. // reassembled datagram
  30. uint FragmentAttackDrops = 0;
  31. extern IP_STATUS SendICMPErr(IPAddr, IPHeader UNALIGNED *, uchar, uchar, ulong, uchar);
  32. extern uint IPSecStatus;
  33. extern IPSecRcvFWPacketRtn IPSecRcvFWPacketPtr;
  34. extern uchar RATimeout;
  35. extern NDIS_HANDLE BufferPool;
  36. extern ProtInfo IPProtInfo[]; // Protocol information table.
  37. extern ProtInfo *LastPI; // Last protinfo structure looked at.
  38. extern int NextPI; // Next PI field to be used.
  39. extern ProtInfo *RawPI; // Raw IP protinfo
  40. extern NetTableEntry **NewNetTableList; // hash table for NTEs
  41. extern uint NET_TABLE_SIZE;
  42. extern NetTableEntry *LoopNTE;
  43. extern IPRcvBuf *g_PerCPUIpBuf; // Global RcvBuf used for proxy perf
  44. // optimization.
  45. extern Interface LoopInterface;
  46. extern uint DisableIPSourceRouting;
  47. uchar CheckLocalOptions(NetTableEntry *SrcNTE, IPHeader UNALIGNED *Header,
  48. IPOptInfo *OptInfo, uchar DestType, uchar* Data,
  49. uint DataSize, BOOLEAN FilterOnDrop);
  50. #define PROT_RSVP 46 // Protocol number for RSVP
  51. //* FindUserRcv - Find the receive handler to be called for a particular
  52. // protocol.
  53. //
  54. // This functions takes as input a protocol value, and returns a pointer to
  55. // the receive routine for that protocol.
  56. //
  57. // Input: NTE - Pointer to NetTableEntry to be searched
  58. // Protocol - Protocol to be searched for.
  59. // UContext - Place to returns UL Context value.
  60. //
  61. // Returns: Pointer to the receive routine.
  62. //
  63. ULRcvProc
  64. FindUserRcv(uchar Protocol)
  65. {
  66. ULRcvProc RcvProc;
  67. int i;
  68. ProtInfo *TempPI;
  69. if (((TempPI = LastPI)->pi_protocol == Protocol) &&
  70. TempPI->pi_valid == PI_ENTRY_VALID) {
  71. RcvProc = TempPI->pi_rcv;
  72. return RcvProc;
  73. }
  74. RcvProc = (ULRcvProc) NULL;
  75. for (i = 0; i < NextPI; i++) {
  76. if (IPProtInfo[i].pi_protocol == Protocol) {
  77. if (IPProtInfo[i].pi_valid == PI_ENTRY_VALID) {
  78. InterlockedExchangePointer(&LastPI, &IPProtInfo[i]);
  79. RcvProc = IPProtInfo[i].pi_rcv;
  80. return RcvProc;
  81. } else {
  82. // Deregisterd entry. Treat this case as if
  83. // there is no matching protocol.
  84. break;
  85. }
  86. }
  87. }
  88. //
  89. // Didn't find a match. Use the raw protocol if it is registered.
  90. //
  91. if ((TempPI = RawPI) != NULL) {
  92. RcvProc = TempPI->pi_rcv;
  93. }
  94. return RcvProc;
  95. }
  96. //* IPRcvComplete - Handle a receive complete.
  97. //
  98. // Called by the lower layer when receives are temporarily done.
  99. //
  100. // Entry: Nothing.
  101. //
  102. // Returns: Nothing.
  103. //
  104. void
  105. __stdcall
  106. IPRcvComplete(void)
  107. {
  108. void (*ULRcvCmpltProc) (void);
  109. int i;
  110. for (i = 0; i < NextPI; i++) {
  111. if (((ULRcvCmpltProc = IPProtInfo[i].pi_rcvcmplt) != NULL) &&
  112. (IPProtInfo[i].pi_valid == PI_ENTRY_VALID)) {
  113. (*ULRcvCmpltProc) ();
  114. }
  115. }
  116. }
  117. //* XsumRcvBuf - Checksum a chain of IP receive buffers.
  118. //
  119. // Called to xsum a chain of IP receive buffers. We're given the
  120. // pseudo-header xsum to start with, and we call xsum on each buffer.
  121. //
  122. // Input: PHXsum - Pseudo-header xsum.
  123. // BufChain - Pointer to IPRcvBuf chain.
  124. //
  125. // Returns: The computed xsum.
  126. //
  127. ushort
  128. XsumRcvBuf(uint PHXsum, IPRcvBuf * BufChain)
  129. {
  130. uint PrevSize = 0;
  131. uint NeedSwap = 0;
  132. PHXsum = (((PHXsum << 16) | (PHXsum >> 16)) + PHXsum) >> 16;
  133. do {
  134. // Whenever an odd number of bytes is checksummed in the interior
  135. // of the buffer-chain, swap the sum and go on so that the next byte
  136. // will overlay the existing sum correctly.
  137. //
  138. // (The correctness of this swap is a property of ones-complement
  139. // checksums.)
  140. if (PrevSize & 1) {
  141. PHXsum = RtlUshortByteSwap(PHXsum);
  142. NeedSwap ^= 1;
  143. }
  144. PHXsum = tcpxsum_routine(PHXsum, BufChain->ipr_buffer,
  145. PrevSize = BufChain->ipr_size);
  146. BufChain = BufChain->ipr_next;
  147. } while (BufChain != NULL);
  148. // If an odd number of swaps were performed, swap once more
  149. // to undo the unmatched swap and obtain the final result.
  150. return NeedSwap ? RtlUshortByteSwap(PHXsum) : (ushort)(PHXsum);
  151. }
  152. //* UpdateIPSecRcvBuf - update an IPRcvBuf after IPSec receive-processing.
  153. //
  154. // Called to perform IPSec-related changes (e.g. setting checksum-verified)
  155. // for an IPRcvBuf.
  156. //
  157. // Input: RcvBuf - Pointer to IPRcvBuf.
  158. // IPSecFlags - Flags for required changes.
  159. //
  160. void
  161. UpdateIPSecRcvBuf(IPRcvBuf* RcvBuf, ulong IPSecFlags)
  162. {
  163. if (IPSecFlags & (IPSEC_FLAG_TCP_CHECKSUM_VALID |
  164. IPSEC_FLAG_UDP_CHECKSUM_VALID) &&
  165. RcvBuf->ipr_pClientCnt) {
  166. PNDIS_PACKET Packet;
  167. PNDIS_PACKET_EXTENSION PktExt;
  168. PNDIS_TCP_IP_CHECKSUM_PACKET_INFO ChksumPktInfo;
  169. if (RcvBuf->ipr_pMdl) {
  170. Packet = NDIS_GET_ORIGINAL_PACKET((PNDIS_PACKET)
  171. RcvBuf->ipr_RcvContext);
  172. if (Packet == NULL) {
  173. Packet = (PNDIS_PACKET)RcvBuf->ipr_RcvContext;
  174. }
  175. } else {
  176. Packet = (PNDIS_PACKET)RcvBuf->ipr_pClientCnt;
  177. }
  178. PktExt = NDIS_PACKET_EXTENSION_FROM_PACKET(Packet);
  179. ChksumPktInfo =
  180. (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)
  181. &PktExt->NdisPacketInfo[TcpIpChecksumPacketInfo];
  182. if (IPSecFlags & IPSEC_FLAG_TCP_CHECKSUM_VALID) {
  183. ChksumPktInfo->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
  184. ChksumPktInfo->Receive.NdisPacketTcpChecksumFailed = FALSE;
  185. }
  186. if (IPSecFlags & IPSEC_FLAG_UDP_CHECKSUM_VALID) {
  187. ChksumPktInfo->Receive.NdisPacketUdpChecksumSucceeded = TRUE;
  188. ChksumPktInfo->Receive.NdisPacketUdpChecksumFailed = FALSE;
  189. }
  190. }
  191. }
  192. //* FindRH - Look up a reassembly header on an NTE.
  193. //
  194. // A utility function to look up a reassembly header. We assume the lock
  195. // on the NTE is taken when we are called. If we find a matching RH
  196. // we'll take the lock on it. We also return the predecessor of the RH,
  197. // for use in insertion or deletion.
  198. //
  199. // Input: PrevRH - Place to return pointer to previous RH
  200. // NTE - NTE to be searched.
  201. // Dest - Destination IP address
  202. // Src - Src IP address
  203. // ID - ID of RH
  204. // Protocol - Protocol of RH
  205. //
  206. // Returns: Pointer to RH, or NULL if none.
  207. //
  208. ReassemblyHeader *
  209. FindRH(ReassemblyHeader ** PrevRH, NetTableEntry * NTE, IPAddr Dest, IPAddr Src, ushort Id,
  210. uchar Protocol)
  211. {
  212. ReassemblyHeader *TempPrev, *Current;
  213. TempPrev = STRUCT_OF(ReassemblyHeader, &NTE->nte_ralist, rh_next);
  214. Current = NTE->nte_ralist;
  215. while (Current != (ReassemblyHeader *) NULL) {
  216. if (Current->rh_dest == Dest && Current->rh_src == Src && Current->rh_id == Id &&
  217. Current->rh_protocol == Protocol)
  218. break;
  219. TempPrev = Current;
  220. Current = Current->rh_next;
  221. }
  222. *PrevRH = TempPrev;
  223. return Current;
  224. }
  225. //* ParseRcvdOptions - Validate incoming options.
  226. //
  227. // Called during reception handling to validate incoming options. We make
  228. // sure that everything is OK as best we can, and find indices for any
  229. // source route option.
  230. //
  231. // Input: OptInfo - Pointer to option info. structure.
  232. // Index - Pointer to optindex struct to be filled in.
  233. //
  234. //
  235. // Returns: Index of error if any, MAX_OPT_SIZE if no errors.
  236. //
  237. uchar
  238. ParseRcvdOptions(IPOptInfo * OptInfo, OptIndex * Index)
  239. {
  240. uint i = 0; // Index variable.
  241. uchar *Options = OptInfo->ioi_options;
  242. uint OptLength = (uint) OptInfo->ioi_optlength;
  243. uchar Length = 0; // Length of option.
  244. uchar Pointer; // Pointer field, for options that use it.
  245. if (OptLength < 3) {
  246. // Options should be at least 3 bytes, in the loop below we scan
  247. // first 3 bytes of the packet for finding code, len and ptr value
  248. return (uchar) IP_OPT_LENGTH;
  249. }
  250. while (i < OptLength && *Options != IP_OPT_EOL) {
  251. if (*Options == IP_OPT_NOP) {
  252. i++;
  253. Options++;
  254. continue;
  255. }
  256. if ((OptLength - i) < 2) {
  257. return (uchar) i; // Not enough space for the length field.
  258. } else if (((Length = Options[IP_OPT_LENGTH]) + i) > OptLength) {
  259. return (uchar) i + (uchar) IP_OPT_LENGTH; // Length exceeds
  260. //options length.
  261. }
  262. Pointer = Options[IP_OPT_DATA] - 1;
  263. if (*Options == IP_OPT_TS) {
  264. if (Length < (MIN_TS_PTR - 1))
  265. return (uchar) i + (uchar) IP_OPT_LENGTH;
  266. if ((Pointer > Length) || (Pointer + 1 < MIN_TS_PTR) || (Pointer % ROUTER_ALERT_SIZE))
  267. return (uchar) i + (uchar) IP_OPT_LENGTH;
  268. Index->oi_tsindex = (uchar) i;
  269. } else {
  270. if (Length < (MIN_RT_PTR - 1))
  271. return (uchar) i + (uchar) IP_OPT_LENGTH;
  272. if (*Options == IP_OPT_LSRR || *Options == IP_OPT_SSRR) {
  273. OptInfo->ioi_flags |= IP_FLAG_SSRR;
  274. if ((Pointer > Length) || (Pointer + 1 < MIN_RT_PTR) || ((Pointer + 1) % ROUTER_ALERT_SIZE))
  275. return (uchar) i + (uchar) IP_OPT_LENGTH;
  276. // A source route option
  277. if (Pointer < Length) { // Route not complete
  278. if ((Length - Pointer) < sizeof(IPAddr))
  279. return (uchar) i + (uchar) IP_OPT_LENGTH;
  280. Index->oi_srtype = *Options;
  281. Index->oi_srindex = (uchar) i;
  282. }
  283. } else {
  284. if (*Options == IP_OPT_RR) {
  285. if ((Pointer > Length) || (Pointer + 1 < MIN_RT_PTR) || ((Pointer + 1) % ROUTER_ALERT_SIZE))
  286. return (uchar) i + (uchar) IP_OPT_LENGTH;
  287. Index->oi_rrindex = (uchar) i;
  288. } else if (*Options == IP_OPT_ROUTER_ALERT) {
  289. Index->oi_rtrindex = (uchar) i;
  290. }
  291. }
  292. }
  293. i += Length;
  294. Options += Length;
  295. }
  296. return MAX_OPT_SIZE;
  297. }
  298. //* IsRtrAlertPacket - Finds whether an IP packet contains rtr alert option.
  299. // Input: Header - Pointer to incoming header.
  300. // Returns: TRUE if packet contains rtr alert option
  301. //
  302. BOOLEAN
  303. IsRtrAlertPacket(IPHeader UNALIGNED * Header)
  304. {
  305. uint HeaderLength;
  306. IPOptInfo OptInfo;
  307. OptIndex Index;
  308. HeaderLength = (Header->iph_verlen & (uchar) ~ IP_VER_FLAG) << 2;
  309. if (HeaderLength <= sizeof(IPHeader)) {
  310. return FALSE;
  311. }
  312. OptInfo.ioi_options = (uchar *) (Header + 1);
  313. OptInfo.ioi_optlength = (uchar) (HeaderLength - sizeof(IPHeader));
  314. Index.oi_rtrindex = MAX_OPT_SIZE;
  315. ParseRcvdOptions(&OptInfo, &Index);
  316. if (Index.oi_rtrindex == MAX_OPT_SIZE) {
  317. return FALSE;
  318. }
  319. return TRUE;
  320. }
  321. BOOLEAN
  322. IsBCastAllowed(IPAddr DestAddr, IPAddr SrcAddr, uchar Protocol,
  323. NetTableEntry *NTE)
  324. {
  325. uchar DestType;
  326. DestType = IsBCastOnNTE(DestAddr, NTE);
  327. // Note that IGMP Queries must be immune to the source
  328. // filter or else we cannot over
  329. if (DestType == DEST_MCAST) {
  330. uint PromiscuousMode = 0;
  331. if (NTE->nte_flags & NTE_VALID) {
  332. PromiscuousMode = NTE->nte_if->if_promiscuousmode;
  333. }
  334. if (!PromiscuousMode) {
  335. DestType = IsMCastSourceAllowed(DestAddr, SrcAddr, Protocol, NTE);
  336. }
  337. }
  338. return IS_BCAST_DEST(DestType);
  339. }
  340. //* BCastRcv - Receive a broadcast or multicast packet.
  341. //
  342. // Called when we have to receive a broadcast packet. We loop through the
  343. // NTE table, calling the upper layer receive protocol for each net which
  344. // matches the receive I/F and for which the destination address is a
  345. // broadcast.
  346. //
  347. // Input: RcvProc - The receive procedure to be called.
  348. // SrcNTE - NTE on which the packet was originally received.
  349. // DestAddr - Destination address.
  350. // SrcAddr - Source address of packet.
  351. // Data - Pointer to received data.
  352. // DataLength - Size in bytes of data
  353. // Protocol - Upper layer protocol being called.
  354. // OptInfo - Pointer to received IP option info.
  355. //
  356. // Returns: Nothing.
  357. //
  358. void
  359. BCastRcv(ULRcvProc RcvProc, NetTableEntry * SrcNTE, IPAddr DestAddr,
  360. IPAddr SrcAddr, IPHeader UNALIGNED * Header, uint HeaderLength,
  361. IPRcvBuf * Data, uint DataLength, uchar Protocol, IPOptInfo * OptInfo)
  362. {
  363. NetTableEntry *CurrentNTE;
  364. const Interface *SrcIF = SrcNTE->nte_if;
  365. ulong Delivered = 0;
  366. uint i;
  367. for (i = 0; i < NET_TABLE_SIZE; i++) {
  368. NetTableEntry *NetTableList = NewNetTableList[i];
  369. for (CurrentNTE = NetTableList;
  370. CurrentNTE != NULL;
  371. CurrentNTE = CurrentNTE->nte_next) {
  372. if ((CurrentNTE->nte_flags & NTE_ACTIVE) &&
  373. (CurrentNTE->nte_if == SrcIF) &&
  374. (IsBCastAllowed(DestAddr, SrcAddr, Protocol, CurrentNTE)
  375. || (SrcNTE == LoopNTE))) {
  376. uchar *saveddata = Data->ipr_buffer;
  377. uint savedlen = Data->ipr_size;
  378. Delivered = 1;
  379. (*RcvProc) (CurrentNTE, DestAddr, SrcAddr, CurrentNTE->nte_addr,
  380. SrcNTE->nte_addr, Header, HeaderLength, Data, DataLength,
  381. IS_BROADCAST, Protocol, OptInfo);
  382. // restore the buffers;
  383. Data->ipr_buffer = saveddata;
  384. Data->ipr_size = savedlen;
  385. }
  386. }
  387. }
  388. if (Delivered) {
  389. IPSIncrementInDeliverCount();
  390. }
  391. }
  392. //
  393. // Macro to send ICMP dest unreachable taking offset
  394. // in to account in the case of IPSEC, and correctly pointing
  395. // to payload part when ipheader is chained to data as in
  396. // the case of loopback sends.
  397. //
  398. #define SEND_ICMP_MSG(TYPE)\
  399. { \
  400. uchar *buf; \
  401. uchar Len = (uchar) (MIN(PayloadLen, \
  402. MAX_ICMP_PAYLOAD_SIZE)); \
  403. buf = CTEAllocMem(Len + HeaderLength); \
  404. if (buf) { \
  405. CTEMemCopy(buf, Header, HeaderLength); \
  406. CTEMemCopy( buf+(uchar)HeaderLength, \
  407. Payload+(uchar)RcvOffset,Len); \
  408. SendICMPErr(DestNTE->nte_addr,(IPHeader *)buf, \
  409. (uchar) ICMP_DEST_UNREACH, \
  410. (uchar) TYPE, 0, (uchar) (Len+HeaderLength)); \
  411. CTEFreeMem(buf); \
  412. } \
  413. }
  414. //* DeliverToUser - Deliver data to a user protocol.
  415. //
  416. // This procedure is called when we have determined that an incoming
  417. // packet belongs here, and any options have been processed. We accept
  418. // it for upper layer processing, which means looking up the receive
  419. // procedure and calling it, or passing it to BCastRcv if neccessary.
  420. //
  421. // Input: SrcNTE - Pointer to NTE on which packet arrived.
  422. // DestNTE - Pointer to NTE that is accepting packet.
  423. // Header - Pointer to IP header of packet.
  424. // HeaderLength - Length of Header in bytes.
  425. // Data - Pointer to IPRcvBuf chain.
  426. // DataLength - Length in bytes of upper layer data.
  427. // OptInfo - Pointer to Option information for this receive.
  428. // DestType - Type of destination - LOCAL, BCAST.
  429. //
  430. // Returns: Nothing.
  431. void
  432. DeliverToUser(NetTableEntry * SrcNTE, NetTableEntry * DestNTE,
  433. IPHeader UNALIGNED * Header, uint HeaderLength, IPRcvBuf * Data,
  434. uint DataLength, IPOptInfo * OptInfo, PNDIS_PACKET Packet, uchar DestType)
  435. {
  436. ULRcvProc rcv;
  437. uint PromiscuousMode;
  438. uint FirewallMode;
  439. uint RcvOffset = 0;
  440. uchar *Payload = Data->ipr_buffer;
  441. uint PayloadLen = Data->ipr_size;
  442. uchar Flags = 0;
  443. PromiscuousMode = SrcNTE->nte_if->if_promiscuousmode;
  444. FirewallMode = ProcessFirewallQ();
  445. //
  446. // Call into IPSEC so he can decrypt the data. Call only for remote packets.
  447. //
  448. if (IPSecHandlerPtr) {
  449. //
  450. // See if IPSEC is enabled, see if it needs to do anything with this
  451. // packet.
  452. //
  453. FORWARD_ACTION Action;
  454. ULONG ipsecByteCount = 0;
  455. ULONG ipsecMTU = 0;
  456. ULONG ipsecFlags = IPSEC_FLAG_INCOMING;
  457. PNDIS_BUFFER newBuf = NULL;
  458. uint Offset = Data->ipr_RcvOffset;
  459. if (!(RefPtrValid(&FilterRefPtr) || (FirewallMode) ||
  460. (PromiscuousMode))) {
  461. // else ipsec is already called in DeliverToUserEx
  462. if (SrcNTE == LoopNTE) {
  463. ipsecFlags |= IPSEC_FLAG_LOOPBACK;
  464. }
  465. if (OptInfo->ioi_flags & IP_FLAG_SSRR) {
  466. ipsecFlags |= IPSEC_FLAG_SSRR;
  467. }
  468. Action = (*IPSecHandlerPtr) (
  469. (PUCHAR) Header,
  470. (PVOID) Data,
  471. SrcNTE->nte_if, // SrcIF
  472. Packet,
  473. &ipsecByteCount,
  474. &ipsecMTU,
  475. (PVOID *) & newBuf,
  476. &ipsecFlags,
  477. DestType);
  478. if (Action != eFORWARD) {
  479. IPSInfo.ipsi_indiscards++;
  480. return;
  481. } else {
  482. //
  483. // Update the data length if IPSEC changed it
  484. // (like by removing the AH)
  485. //
  486. DataLength -= ipsecByteCount;
  487. RcvOffset = Data->ipr_RcvOffset - Offset;
  488. UpdateIPSecRcvBuf(Data, ipsecFlags);
  489. }
  490. }
  491. }
  492. //
  493. // Clear flags, except the loopback one.
  494. //
  495. Data->ipr_flags &= IPR_FLAG_LOOPBACK_PACKET;
  496. // This tracks whether the interface is bound or not to a particular
  497. // processor. The only transport protocol that cares about this is TCP.
  498. if (Header->iph_protocol == PROTOCOL_TCP) {
  499. // If the media type is Ethernet and the packet was indicated by means
  500. // of Receive-handler and this is the first packet on this interface or
  501. // the current processor is same as the one the previous packet was
  502. // indicated on, we hope that this interface is bound.
  503. if (SrcNTE->nte_if->if_mediatype == IF_TYPE_IS088023_CSMACD) {
  504. if (Data->ipr_pMdl &&
  505. ((SrcNTE->nte_if->if_lastproc == (int)KeGetCurrentProcessorNumber()) ||
  506. (SrcNTE->nte_if->if_lastproc == (int)KeNumberProcessors))) {
  507. Flags |= IS_BOUND;
  508. }
  509. SrcNTE->nte_if->if_lastproc = KeGetCurrentProcessorNumber();
  510. } else if (SrcNTE->nte_if == &LoopInterface) {
  511. Flags |= IS_BOUND;
  512. }
  513. }
  514. // Process this request right now. Look up the protocol. If we
  515. // find it, copy the data if we need to, and call the protocol's
  516. // receive handler. If we don't find it, send an ICMP
  517. // 'protocol unreachable' message.
  518. rcv = FindUserRcv(Header->iph_protocol);
  519. if (!PromiscuousMode) {
  520. if (rcv != NULL) {
  521. IP_STATUS Status;
  522. if (DestType == DEST_LOCAL) {
  523. Status = (*rcv) (SrcNTE, Header->iph_dest, Header->iph_src,
  524. DestNTE->nte_addr, SrcNTE->nte_addr, Header,
  525. HeaderLength, Data, DataLength, Flags,
  526. Header->iph_protocol, OptInfo);
  527. if (Status == IP_SUCCESS) {
  528. IPSIncrementInDeliverCount();
  529. return;
  530. }
  531. if (Status == IP_DEST_PROT_UNREACHABLE) {
  532. IPSInfo.ipsi_inunknownprotos++;
  533. SEND_ICMP_MSG(PROT_UNREACH);
  534. } else {
  535. IPSIncrementInDeliverCount();
  536. SEND_ICMP_MSG(PORT_UNREACH);
  537. }
  538. return; // Just return out of here now.
  539. } else if (DestType < DEST_REMOTE) { // BCAST, SN_BCAST, MCAST
  540. BCastRcv(rcv, SrcNTE, Header->iph_dest, Header->iph_src,
  541. Header, HeaderLength, Data, DataLength,
  542. Header->iph_protocol, OptInfo);
  543. } else {
  544. // DestType >= DEST_REMOTE
  545. // Force Rcv protocol to be Raw
  546. rcv = NULL;
  547. if (RawPI != NULL) {
  548. rcv = RawPI->pi_rcv;
  549. }
  550. if ((rcv != NULL) && (DestType != DEST_INVALID)) {
  551. Data->ipr_flags |= IPR_FLAG_PROMISCUOUS;
  552. Status = (*rcv) (SrcNTE,Header->iph_dest,Header->iph_src,
  553. DestNTE->nte_addr, SrcNTE->nte_addr, Header,
  554. HeaderLength, Data, DataLength, FALSE,
  555. Header->iph_protocol, OptInfo);
  556. }
  557. return; // Just return out of here now.
  558. }
  559. } else {
  560. IPSInfo.ipsi_inunknownprotos++;
  561. // If we get here, we didn't find a matching protocol. Send an
  562. // ICMP message.
  563. SEND_ICMP_MSG(PROT_UNREACH);
  564. }
  565. } else { // PromiscuousMode = 1
  566. IP_STATUS Status;
  567. if (DestType == DEST_LOCAL) {
  568. if (rcv != NULL) {
  569. uchar *saveddata = Data->ipr_buffer;
  570. uint savedlen = Data->ipr_size;
  571. Data->ipr_flags |= IPR_FLAG_PROMISCUOUS;
  572. Status = (*rcv) (SrcNTE, Header->iph_dest, Header->iph_src,
  573. DestNTE->nte_addr, SrcNTE->nte_addr, Header,
  574. HeaderLength, Data, DataLength, Flags,
  575. Header->iph_protocol, OptInfo);
  576. if (Status == IP_SUCCESS) {
  577. IPSIncrementInDeliverCount();
  578. // If succeed and promiscuous mode set
  579. // also do a raw rcv if previous wasn't a RawRcv
  580. if ((RawPI != NULL) && (RawPI->pi_rcv != NULL) && (RawPI->pi_rcv != rcv)) {
  581. // we hv registered for RAW protocol
  582. rcv = RawPI->pi_rcv;
  583. // restore the buffers;
  584. Data->ipr_buffer = saveddata;
  585. Data->ipr_size = savedlen;
  586. Status = (*rcv) (SrcNTE, Header->iph_dest, Header->iph_src,
  587. DestNTE->nte_addr, SrcNTE->nte_addr, Header,
  588. HeaderLength, Data, DataLength, FALSE,
  589. Header->iph_protocol, OptInfo);
  590. }
  591. return;
  592. }
  593. if (Status == IP_DEST_PROT_UNREACHABLE) {
  594. IPSInfo.ipsi_inunknownprotos++;
  595. SEND_ICMP_MSG(PROT_UNREACH);
  596. } else {
  597. IPSIncrementInDeliverCount();
  598. SEND_ICMP_MSG(PORT_UNREACH);
  599. }
  600. } else {
  601. IPSInfo.ipsi_inunknownprotos++;
  602. // If we get here, we didn't find a matching protocol. Send
  603. // an ICMP message.
  604. SEND_ICMP_MSG(PROT_UNREACH);
  605. }
  606. return; // Just return out of here now.
  607. } else if (DestType < DEST_REMOTE) { // BCAST, SN_BCAST, MCAST
  608. uchar *saveddata = Data->ipr_buffer;
  609. uint savedlen = Data->ipr_size;
  610. if (rcv != NULL) {
  611. Data->ipr_flags |= IPR_FLAG_PROMISCUOUS;
  612. BCastRcv(rcv, SrcNTE, Header->iph_dest, Header->iph_src,
  613. Header, HeaderLength, Data, DataLength,
  614. Header->iph_protocol, OptInfo);
  615. // If succeed and promiscuous mode set
  616. // also do a raw rcv if previous is not RawRcv
  617. if ((RawPI != NULL) && (RawPI->pi_rcv != NULL) && (RawPI->pi_rcv != rcv)) {
  618. // we hv registered for RAW protocol
  619. rcv = RawPI->pi_rcv;
  620. Data->ipr_buffer = saveddata;
  621. Data->ipr_size = savedlen;
  622. Status = (*rcv) (SrcNTE, Header->iph_dest, Header->iph_src,
  623. DestNTE->nte_addr, SrcNTE->nte_addr, Header,
  624. HeaderLength, Data, DataLength, FALSE,
  625. Header->iph_protocol, OptInfo);
  626. }
  627. } else {
  628. IPSInfo.ipsi_inunknownprotos++;
  629. // If we get here, we didn't find a matching protocol. Send an ICMP message.
  630. SEND_ICMP_MSG(PROT_UNREACH);
  631. }
  632. } else { // DestType >= DEST_REMOTE and promiscuous mode set
  633. // Force Rcv protocol to be Raw
  634. rcv = NULL;
  635. if (RawPI != NULL) {
  636. rcv = RawPI->pi_rcv;
  637. }
  638. if ((rcv != NULL) && (DestType != DEST_INVALID)) {
  639. Data->ipr_flags |= IPR_FLAG_PROMISCUOUS;
  640. Status = (*rcv) (SrcNTE, Header->iph_dest, Header->iph_src,
  641. DestNTE->nte_addr, SrcNTE->nte_addr, Header,
  642. HeaderLength, Data, DataLength, FALSE,
  643. Header->iph_protocol, OptInfo);
  644. return; // Just return out of here now.
  645. } else {
  646. if (rcv == NULL) {
  647. KdPrint(("Rcv is NULL \n"));
  648. } else {
  649. KdPrint(("Dest invalid \n"));
  650. }
  651. }
  652. } // DestType >= DEST_REMOTE
  653. } // Promiscuous Mode
  654. }
  655. uchar *
  656. ConvertIPRcvBufToFlatBuffer(IPRcvBuf * pRcvBuf, uint DataLength)
  657. {
  658. uchar *pBuff;
  659. IPRcvBuf *tmpRcvBuf;
  660. uint FrwlOffset;
  661. // convert RcvBuf chain to a flat buffer
  662. tmpRcvBuf = pRcvBuf;
  663. FrwlOffset = 0;
  664. pBuff = CTEAllocMemN(DataLength, 'aiCT');
  665. if (pBuff) {
  666. while (tmpRcvBuf != NULL) {
  667. ASSERT(tmpRcvBuf->ipr_buffer != NULL);
  668. RtlCopyMemory(pBuff + FrwlOffset, tmpRcvBuf->ipr_buffer, tmpRcvBuf->ipr_size);
  669. FrwlOffset += tmpRcvBuf->ipr_size;
  670. tmpRcvBuf = tmpRcvBuf->ipr_next;
  671. }
  672. }
  673. return pBuff;
  674. }
  675. //* DeliverToUserEx - Called when (IPSEC & Filter)/Firewall/Promiscuous set
  676. //
  677. // Input: SrcNTE - Pointer to NTE on which packet arrived.
  678. // DestNTE - Pointer to NTE that is accepting packet.
  679. // Header - Pointer to IP header of packet.
  680. // HeaderLength - Length of Header in bytes.
  681. // Data - Pointer to IPRcvBuf chain.
  682. // DataLength - Length in bytes of upper layer data +
  683. // HeaderLength.
  684. // OptInfo - Pointer to Option information for this receive.
  685. // DestType - Type of destination - LOCAL, BCAST.
  686. //
  687. // It is assumed that if firewall is present Data contains IPHeader also.
  688. // Also, DataLength includes HeaderLength in this case
  689. //
  690. // Returns: Nothing.
  691. void
  692. DeliverToUserEx(NetTableEntry * SrcNTE, NetTableEntry * DestNTE,
  693. IPHeader UNALIGNED * Header, uint HeaderLength, IPRcvBuf * Data,
  694. uint DataLength, IPOptInfo * OptInfo, PNDIS_PACKET Packet, uchar DestType, LinkEntry * LinkCtxt)
  695. {
  696. uint PromiscuousMode;
  697. uint FirewallMode;
  698. uint FirewallRef;
  699. Queue* FirewallQ;
  700. uint FastPath;
  701. IPRcvBuf *tmpRcvBuf;
  702. uchar *pBuff;
  703. BOOLEAN OneChunk;
  704. PromiscuousMode = SrcNTE->nte_if->if_promiscuousmode;
  705. FirewallMode = ProcessFirewallQ();
  706. if (DestType == DEST_PROMIS) {
  707. // We don't call any hook for this packet
  708. // if firewall is there take the header off
  709. // and then delivertouser
  710. if (FirewallMode) {
  711. if (Data->ipr_size > HeaderLength) { //1st buff contains data also
  712. uchar *saveddata = Data->ipr_buffer;
  713. Data->ipr_buffer += HeaderLength;
  714. Data->ipr_size -= HeaderLength;
  715. DataLength -= HeaderLength;
  716. DeliverToUser(SrcNTE, DestNTE, Header, HeaderLength, Data, DataLength, OptInfo, NULL, DestType);
  717. // restore the buffers;
  718. Data->ipr_buffer = saveddata;
  719. Data->ipr_size += HeaderLength;
  720. IPFreeBuff(Data);
  721. } else { // First buffer just contains Header
  722. uchar *saveddata;
  723. if (Data->ipr_next == NULL) {
  724. // we received the data s.t. datasize == headersize
  725. IPSInfo.ipsi_indiscards++;
  726. IPFreeBuff(Data);
  727. return;
  728. }
  729. saveddata = Data->ipr_next->ipr_buffer;
  730. DataLength -= HeaderLength;
  731. DeliverToUser(SrcNTE, DestNTE, Header, HeaderLength, Data->ipr_next, DataLength, OptInfo, NULL, DestType);
  732. // restore the buffers;
  733. Data->ipr_next->ipr_buffer = saveddata;
  734. IPFreeBuff(Data);
  735. }
  736. } else { // FirewallMode is 0
  737. DeliverToUser(SrcNTE, DestNTE, Header, HeaderLength,
  738. Data, DataLength, OptInfo, NULL, DestType);
  739. }
  740. return;
  741. }
  742. if (DestType >= DEST_REMOTE) {
  743. // Packet would have gone to the forward path, normally
  744. // Call the filter/firewall hook if its there
  745. if (FirewallMode) {
  746. FORWARD_ACTION Action = FORWARD;
  747. FIREWALL_CONTEXT_T FrCtx;
  748. IPAddr DAddr = Header->iph_dest;
  749. IPRcvBuf *pRcvBuf = Data;
  750. IPRcvBuf *pOutRcvBuf = NULL;
  751. NetTableEntry *DstNTE;
  752. Queue *CurrQ;
  753. FIREWALL_HOOK *CurrHook;
  754. uint DestIFIndex = INVALID_IF_INDEX;
  755. uchar DestinationType = DestType;
  756. uint BufferChanged = 0;
  757. FrCtx.Direction = IP_RECEIVE;
  758. FrCtx.NTE = SrcNTE; //NTE the dg arrived on
  759. FrCtx.LinkCtxt = LinkCtxt;
  760. if (pRcvBuf->ipr_size > HeaderLength) { //1st buffer contains data also
  761. FastPath = 1;
  762. } else {
  763. FastPath = 0;
  764. if (pRcvBuf->ipr_next == NULL) {
  765. // we received the data s.t. datasize == headersize
  766. IPSInfo.ipsi_indiscards++;
  767. IPFreeBuff(pRcvBuf);
  768. return;
  769. }
  770. }
  771. // Call the filter hook if installed
  772. if (RefPtrValid(&FilterRefPtr)) {
  773. IPPacketFilterPtr FilterPtr;
  774. FORWARD_ACTION Action = FORWARD;
  775. if (FastPath) {
  776. // first buffer contains data also
  777. Interface *IF = SrcNTE->nte_if;
  778. IPAddr LinkNextHop;
  779. if ((IF->if_flags & IF_FLAGS_P2MP) && LinkCtxt) {
  780. LinkNextHop = LinkCtxt->link_NextHop;
  781. } else {
  782. LinkNextHop = NULL_IP_ADDR;
  783. }
  784. FilterPtr = AcquireRefPtr(&FilterRefPtr);
  785. Action = (*FilterPtr) ( Header,
  786. pRcvBuf->ipr_buffer + HeaderLength,
  787. pRcvBuf->ipr_size - HeaderLength,
  788. IF->if_index,
  789. INVALID_IF_INDEX,
  790. LinkNextHop,
  791. NULL_IP_ADDR);
  792. ReleaseRefPtr(&FilterRefPtr);
  793. } else { // Fast Path = 0
  794. // first buffer contains IPHeader only
  795. Interface *IF = SrcNTE->nte_if;
  796. IPAddr LinkNextHop;
  797. if ((IF->if_flags & IF_FLAGS_P2MP) && LinkCtxt) {
  798. LinkNextHop = LinkCtxt->link_NextHop;
  799. } else {
  800. LinkNextHop = NULL_IP_ADDR;
  801. }
  802. FilterPtr = AcquireRefPtr(&FilterRefPtr);
  803. Action = (*FilterPtr) (Header,
  804. pRcvBuf->ipr_next->ipr_buffer,
  805. pRcvBuf->ipr_next->ipr_size,
  806. IF->if_index,
  807. INVALID_IF_INDEX,
  808. LinkNextHop,
  809. NULL_IP_ADDR);
  810. ReleaseRefPtr(&FilterRefPtr);
  811. }
  812. if (Action != FORWARD) {
  813. IPSInfo.ipsi_indiscards++;
  814. IPFreeBuff(pRcvBuf);
  815. return;
  816. }
  817. }
  818. // call the firewallhook from front;
  819. // in xmit path we call it from rear
  820. #if MILLEN
  821. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  822. #else // MILLEN
  823. ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
  824. #endif // MILLEN
  825. FirewallRef = RefFirewallQ(&FirewallQ);
  826. CurrQ = QHEAD(FirewallQ);
  827. while (CurrQ != QEND(FirewallQ)) {
  828. CurrHook = QSTRUCT(FIREWALL_HOOK, CurrQ, hook_q);
  829. pOutRcvBuf = NULL;
  830. // pOutRcvBuf is assumed to be NULL before firewall hook is
  831. //called
  832. Action = (*CurrHook->hook_Ptr) (&pRcvBuf,
  833. SrcNTE->nte_if->if_index,
  834. &DestIFIndex,
  835. &DestinationType,
  836. &FrCtx,
  837. sizeof(FrCtx),
  838. &pOutRcvBuf);
  839. if (Action == DROP) {
  840. DerefFirewallQ(FirewallRef);
  841. #if MILLEN
  842. KeLowerIrql(OldIrql);
  843. #endif // MILLEN
  844. IPSInfo.ipsi_indiscards++;
  845. if (pRcvBuf != NULL) {
  846. IPFreeBuff(pRcvBuf);
  847. }
  848. if (pOutRcvBuf != NULL) {
  849. IPFreeBuff(pOutRcvBuf);
  850. }
  851. IPSInfo.ipsi_indiscards++;
  852. return;
  853. } else {
  854. ASSERT(Action == FORWARD);
  855. if (pOutRcvBuf != NULL) {
  856. // free the old buffer
  857. if (pRcvBuf != NULL) {
  858. IPFreeBuff(pRcvBuf);
  859. }
  860. pRcvBuf = pOutRcvBuf;
  861. BufferChanged = 1;
  862. }
  863. }
  864. CurrQ = QNEXT(CurrQ);
  865. }
  866. DerefFirewallQ(FirewallRef);
  867. #if MILLEN
  868. KeLowerIrql(OldIrql);
  869. #endif // MILLEN
  870. ASSERT(Action == FORWARD);
  871. if (BufferChanged) {
  872. // if packet touched compute the new length: DataSize
  873. DataLength = 0;
  874. tmpRcvBuf = pRcvBuf;
  875. while (tmpRcvBuf != NULL) {
  876. ASSERT(tmpRcvBuf->ipr_buffer != NULL);
  877. DataLength += tmpRcvBuf->ipr_size;
  878. tmpRcvBuf = tmpRcvBuf->ipr_next;
  879. }
  880. // also make Header point to new buffer
  881. Header = (IPHeader *) pRcvBuf->ipr_buffer;
  882. HeaderLength = (Header->iph_verlen & 0xf) << 2;
  883. }
  884. DataLength -= HeaderLength; // decrement the header length
  885. if (DestinationType == DEST_INVALID) { // Dest Addr changed by hook
  886. DAddr = Header->iph_dest;
  887. DstNTE = SrcNTE;
  888. DestType = GetLocalNTE(DAddr, &DstNTE);
  889. DestNTE = DstNTE;
  890. }
  891. if (DestType < DEST_REMOTE) {
  892. // Check to see options
  893. if (HeaderLength != sizeof(IPHeader)) {
  894. // We have options
  895. uchar NewDType;
  896. NewDType = CheckLocalOptions(
  897. SrcNTE,
  898. (IPHeader UNALIGNED *) Header,
  899. OptInfo,
  900. DestType,
  901. NULL,
  902. 0,
  903. FALSE);
  904. if (NewDType != DEST_LOCAL) {
  905. if (NewDType == DEST_REMOTE) {
  906. if (PromiscuousMode) {
  907. if (FastPath) {
  908. uchar *saveddata = pRcvBuf->ipr_buffer;
  909. pRcvBuf->ipr_buffer += HeaderLength;
  910. pRcvBuf->ipr_size -= HeaderLength;
  911. DeliverToUser(
  912. SrcNTE,
  913. DestNTE,
  914. (IPHeader UNALIGNED *) Header,
  915. HeaderLength,
  916. pRcvBuf,
  917. DataLength,
  918. OptInfo,
  919. NULL,
  920. DestType);
  921. // restore the buffer
  922. pRcvBuf->ipr_buffer = saveddata;
  923. pRcvBuf->ipr_size += HeaderLength;
  924. } else {
  925. uchar *saveddata = pRcvBuf->ipr_next->ipr_buffer;
  926. DeliverToUser(
  927. SrcNTE,
  928. DestNTE,
  929. (IPHeader UNALIGNED *)Header,
  930. HeaderLength,
  931. pRcvBuf->ipr_next,
  932. DataLength,
  933. OptInfo,
  934. NULL,
  935. DestType);
  936. // restore the buffers;
  937. pRcvBuf->ipr_next->ipr_buffer = saveddata;
  938. }
  939. }
  940. goto forward_remote;
  941. } else {
  942. IPSInfo.ipsi_inhdrerrors++;
  943. IPFreeBuff(pRcvBuf);
  944. //CTEFreeMem(pBuff);
  945. return; // Bad Options
  946. }
  947. } // NewDtype != LOCAL
  948. } // Options present
  949. } // DestType < DEST_REMOTE
  950. else { // DestType >=DEST_REMOTE
  951. if (PromiscuousMode) {
  952. if (FastPath) {
  953. uchar *savedata = pRcvBuf->ipr_buffer;
  954. pRcvBuf->ipr_buffer += HeaderLength;
  955. pRcvBuf->ipr_size -= HeaderLength;
  956. DeliverToUser(SrcNTE,
  957. DestNTE, (IPHeader UNALIGNED *) Header,
  958. HeaderLength,pRcvBuf, DataLength,
  959. OptInfo, NULL, DestType);
  960. // restore the buffer
  961. pRcvBuf->ipr_buffer = savedata;
  962. pRcvBuf->ipr_size += HeaderLength;
  963. } else {
  964. uchar *saveddata = pRcvBuf->ipr_next->ipr_buffer;
  965. DeliverToUser(SrcNTE, DestNTE,
  966. (IPHeader UNALIGNED *)Header,HeaderLength,
  967. pRcvBuf->ipr_next, DataLength, OptInfo,
  968. NULL, DestType);
  969. // restore the buffers;
  970. pRcvBuf->ipr_next->ipr_buffer = saveddata;
  971. }
  972. }
  973. goto forward_remote;
  974. }
  975. // DestType <= DEST_REMOTE
  976. if (FastPath) {
  977. uchar *saveddata = pRcvBuf->ipr_buffer;
  978. pRcvBuf->ipr_buffer += HeaderLength;
  979. pRcvBuf->ipr_size -= HeaderLength;
  980. DeliverToUser(SrcNTE, DestNTE, (IPHeader UNALIGNED *) Header,
  981. HeaderLength,pRcvBuf, DataLength, OptInfo, NULL,
  982. DestType);
  983. // restore the buffer
  984. pRcvBuf->ipr_buffer = saveddata;
  985. pRcvBuf->ipr_size += HeaderLength;
  986. } else {
  987. uchar *saveddata = pRcvBuf->ipr_next->ipr_buffer;
  988. DeliverToUser(SrcNTE, DestNTE, (IPHeader UNALIGNED *) Header,
  989. HeaderLength, pRcvBuf->ipr_next, DataLength,
  990. OptInfo, NULL, DestType);
  991. // restore the buffers;
  992. pRcvBuf->ipr_next->ipr_buffer = saveddata;
  993. }
  994. if (IS_BCAST_DEST(DestType)) {
  995. OneChunk = FALSE;
  996. if (pRcvBuf->ipr_next == NULL) {
  997. OneChunk = TRUE;
  998. pBuff = pRcvBuf->ipr_buffer;
  999. } else {
  1000. pBuff = ConvertIPRcvBufToFlatBuffer(pRcvBuf,
  1001. DataLength + HeaderLength);
  1002. if (!pBuff) {
  1003. IPSInfo.ipsi_indiscards++;
  1004. IPFreeBuff(pRcvBuf);
  1005. return;
  1006. }
  1007. }
  1008. if (!(pRcvBuf->ipr_flags & IPR_FLAG_LOOPBACK_PACKET)) {
  1009. IPForwardPkt(SrcNTE, (IPHeader UNALIGNED *) pBuff,
  1010. HeaderLength, pBuff + HeaderLength, DataLength,
  1011. NULL, 0, DestType, 0, NULL, NULL, LinkCtxt);
  1012. }
  1013. if (!OneChunk) {
  1014. CTEFreeMem(pBuff); // free the flat buffer
  1015. }
  1016. }
  1017. IPFreeBuff(pRcvBuf);
  1018. return;
  1019. forward_remote:
  1020. OneChunk = FALSE;
  1021. if (pRcvBuf->ipr_next == NULL) {
  1022. OneChunk = TRUE;
  1023. pBuff = pRcvBuf->ipr_buffer;
  1024. } else {
  1025. pBuff = ConvertIPRcvBufToFlatBuffer(pRcvBuf,
  1026. DataLength + HeaderLength);
  1027. if (!pBuff) {
  1028. IPSInfo.ipsi_indiscards++;
  1029. IPFreeBuff(pRcvBuf);
  1030. return;
  1031. }
  1032. }
  1033. //
  1034. // Calling fwd routine for loopback packets results
  1035. // in stack overflow. Check for this.
  1036. //
  1037. if (!(pRcvBuf->ipr_flags & IPR_FLAG_LOOPBACK_PACKET)) {
  1038. IPForwardPkt(SrcNTE, (IPHeader UNALIGNED *) pBuff, HeaderLength,
  1039. pBuff + HeaderLength, DataLength, NULL, 0,
  1040. DestType, 0, NULL, NULL, LinkCtxt);
  1041. }
  1042. IPFreeBuff(pRcvBuf);
  1043. if (!OneChunk) {
  1044. CTEFreeMem(pBuff); // free the flat buffer
  1045. }
  1046. return;
  1047. } else { // No Firewall
  1048. if (PromiscuousMode) {
  1049. DeliverToUser(SrcNTE, DestNTE, (IPHeader UNALIGNED *) Header,
  1050. HeaderLength, Data, DataLength, OptInfo, NULL,
  1051. DestType);
  1052. }
  1053. // Convert IPRcvBuf chain to a flat buffer
  1054. OneChunk = FALSE;
  1055. if (Data != NULL && !Data->ipr_next) {
  1056. OneChunk = TRUE;
  1057. pBuff = Data->ipr_buffer;
  1058. } else {
  1059. pBuff = ConvertIPRcvBufToFlatBuffer(
  1060. Data, DataLength + HeaderLength);
  1061. if (!pBuff) {
  1062. IPSInfo.ipsi_indiscards++;
  1063. return;
  1064. }
  1065. }
  1066. if (!(Data->ipr_flags & IPR_FLAG_LOOPBACK_PACKET)) {
  1067. IPForwardPkt(SrcNTE, (IPHeader UNALIGNED *) Header, HeaderLength,
  1068. pBuff, DataLength, NULL, 0, DestType, 0, NULL, NULL,
  1069. LinkCtxt);
  1070. }
  1071. if (!OneChunk) CTEFreeMem(pBuff);
  1072. }
  1073. return;
  1074. } // DestType >= DEST_REMOTE
  1075. ASSERT(DestType <= DEST_REMOTE);
  1076. // Call IPSEC -> Filter -> Firewall
  1077. // These are local packets only.
  1078. if (FirewallMode) { // Header is part of the Data
  1079. FORWARD_ACTION Action = FORWARD;
  1080. FIREWALL_CONTEXT_T FrCtx;
  1081. IPAddr DAddr = Header->iph_dest;
  1082. IPRcvBuf *pRcvBuf = Data;
  1083. IPRcvBuf *pOutRcvBuf = NULL;
  1084. NetTableEntry *DstNTE;
  1085. Queue *CurrQ;
  1086. FIREWALL_HOOK *CurrHook;
  1087. uint DestIFIndex = LOCAL_IF_INDEX;
  1088. uchar DestinationType = DestType;
  1089. uint BufferChanged = 0;
  1090. ULONG ipsecFlags = IPSEC_FLAG_INCOMING;
  1091. if (pRcvBuf->ipr_size > HeaderLength) { //1st buffer contains data also
  1092. FastPath = 1;
  1093. } else {
  1094. FastPath = 0;
  1095. if (pRcvBuf->ipr_next == NULL) {
  1096. // we received the data s.t. datasize == headersize
  1097. IPSInfo.ipsi_indiscards++;
  1098. IPFreeBuff(pRcvBuf);
  1099. return;
  1100. }
  1101. }
  1102. //
  1103. // Call into IPSEC so he can decrypt the data
  1104. //
  1105. // In case of firewall make sure we pass the data only but we don't actually strip the header
  1106. if (IPSecHandlerPtr) {
  1107. //
  1108. // See if IPSEC is enabled, see if it needs to do anything with this
  1109. // packet.
  1110. //
  1111. FORWARD_ACTION Action;
  1112. ULONG ipsecByteCount = 0;
  1113. ULONG ipsecMTU = 0;
  1114. PNDIS_BUFFER newBuf = NULL;
  1115. if (SrcNTE == LoopNTE) {
  1116. ipsecFlags |= IPSEC_FLAG_LOOPBACK;
  1117. }
  1118. if (OptInfo->ioi_flags & IP_FLAG_SSRR) {
  1119. ipsecFlags |= IPSEC_FLAG_SSRR;
  1120. }
  1121. if (FastPath) {
  1122. // first buffer contains IPHeader also
  1123. pRcvBuf->ipr_buffer += HeaderLength;
  1124. pRcvBuf->ipr_size -= HeaderLength;
  1125. // this tells IPSEC to move IPHeader after decryption
  1126. ipsecFlags |= IPSEC_FLAG_FASTRCV;
  1127. Action = (*IPSecHandlerPtr) (
  1128. (PUCHAR) Header,
  1129. (PVOID) pRcvBuf,
  1130. SrcNTE->nte_if, // SrcIF
  1131. Packet,
  1132. &ipsecByteCount,
  1133. &ipsecMTU,
  1134. (PVOID *) & newBuf,
  1135. &ipsecFlags,
  1136. DestType);
  1137. // restore the buffer
  1138. pRcvBuf->ipr_buffer -= HeaderLength;
  1139. pRcvBuf->ipr_size += HeaderLength;
  1140. Header = (IPHeader UNALIGNED *)pRcvBuf->ipr_buffer;
  1141. } else { // FastPath = 0
  1142. Action = (*IPSecHandlerPtr) (
  1143. (PUCHAR) Header,
  1144. (PVOID) (pRcvBuf->ipr_next),
  1145. SrcNTE->nte_if, // SrcIF
  1146. Packet,
  1147. &ipsecByteCount,
  1148. &ipsecMTU,
  1149. (PVOID *) & newBuf,
  1150. &ipsecFlags,
  1151. DestType);
  1152. }
  1153. if (Action != eFORWARD) {
  1154. IPSInfo.ipsi_indiscards++;
  1155. IPFreeBuff(pRcvBuf);
  1156. return;
  1157. } else {
  1158. //
  1159. // Update the data length if IPSEC changed it (like by removing the AH)
  1160. //
  1161. DataLength -= ipsecByteCount;
  1162. UpdateIPSecRcvBuf(pRcvBuf, ipsecFlags);
  1163. }
  1164. }
  1165. // If ipsec acted on this, mark ipr_flags for
  1166. // filter driver.
  1167. if (ipsecFlags & IPSEC_FLAG_TRANSFORMED) {
  1168. pRcvBuf->ipr_flags |= IPR_FLAG_IPSEC_TRANSFORMED;
  1169. }
  1170. // Call the filter hook if installed
  1171. if (RefPtrValid(&FilterRefPtr)) {
  1172. IPPacketFilterPtr FilterPtr;
  1173. FORWARD_ACTION Action = FORWARD;
  1174. if (FastPath) {
  1175. Interface *IF = SrcNTE->nte_if;
  1176. IPAddr LinkNextHop;
  1177. if ((IF->if_flags & IF_FLAGS_P2MP) && LinkCtxt) {
  1178. LinkNextHop = LinkCtxt->link_NextHop;
  1179. } else {
  1180. LinkNextHop = NULL_IP_ADDR;
  1181. }
  1182. FilterPtr = AcquireRefPtr(&FilterRefPtr);
  1183. Action = (*FilterPtr) (Header,
  1184. pRcvBuf->ipr_buffer + HeaderLength,
  1185. pRcvBuf->ipr_size - HeaderLength,
  1186. IF->if_index,
  1187. INVALID_IF_INDEX,
  1188. LinkNextHop,
  1189. NULL_IP_ADDR);
  1190. ReleaseRefPtr(&FilterRefPtr);
  1191. } else { // Fast Path = 0
  1192. Interface *IF = SrcNTE->nte_if;
  1193. IPAddr LinkNextHop;
  1194. if ((IF->if_flags & IF_FLAGS_P2MP) && LinkCtxt) {
  1195. LinkNextHop = LinkCtxt->link_NextHop;
  1196. } else {
  1197. LinkNextHop = NULL_IP_ADDR;
  1198. }
  1199. FilterPtr = AcquireRefPtr(&FilterRefPtr);
  1200. Action = (*FilterPtr) (Header,
  1201. pRcvBuf->ipr_next->ipr_buffer,
  1202. pRcvBuf->ipr_next->ipr_size,
  1203. IF->if_index,
  1204. INVALID_IF_INDEX,
  1205. LinkNextHop,
  1206. NULL_IP_ADDR);
  1207. ReleaseRefPtr(&FilterRefPtr);
  1208. }
  1209. if (Action != FORWARD) {
  1210. IPSInfo.ipsi_indiscards++;
  1211. IPFreeBuff(pRcvBuf);
  1212. return;
  1213. }
  1214. }
  1215. // Call the firewall hook
  1216. FrCtx.Direction = IP_RECEIVE;
  1217. FrCtx.NTE = SrcNTE; //NTE the dg arrived on
  1218. FrCtx.LinkCtxt = LinkCtxt;
  1219. // call the firewall hooks from front of the Queue
  1220. #if MILLEN
  1221. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  1222. #else // MILLEN
  1223. ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
  1224. #endif // MILLEN
  1225. FirewallRef = RefFirewallQ(&FirewallQ);
  1226. CurrQ = QHEAD(FirewallQ);
  1227. while (CurrQ != QEND(FirewallQ)) {
  1228. CurrHook = QSTRUCT(FIREWALL_HOOK, CurrQ, hook_q);
  1229. pOutRcvBuf = NULL;
  1230. Action = (*CurrHook->hook_Ptr) (&pRcvBuf,
  1231. SrcNTE->nte_if->if_index,
  1232. &DestIFIndex,
  1233. &DestinationType,
  1234. &FrCtx,
  1235. sizeof(FrCtx),
  1236. &pOutRcvBuf);
  1237. if (Action == DROP) {
  1238. DerefFirewallQ(FirewallRef);
  1239. #if MILLEN
  1240. KeLowerIrql(OldIrql);
  1241. #endif // MILLEN
  1242. IPSInfo.ipsi_indiscards++;
  1243. if (pRcvBuf != NULL) {
  1244. IPFreeBuff(pRcvBuf);
  1245. }
  1246. if (pOutRcvBuf != NULL) {
  1247. IPFreeBuff(pOutRcvBuf);
  1248. }
  1249. return;
  1250. } else {
  1251. ASSERT(Action == FORWARD);
  1252. if (pOutRcvBuf != NULL) {
  1253. // free the old buffer
  1254. if (pRcvBuf != NULL) {
  1255. IPFreeBuff(pRcvBuf);
  1256. }
  1257. pRcvBuf = pOutRcvBuf;
  1258. BufferChanged = 1;
  1259. }
  1260. }
  1261. CurrQ = QNEXT(CurrQ);
  1262. }
  1263. DerefFirewallQ(FirewallRef);
  1264. #if MILLEN
  1265. KeLowerIrql(OldIrql);
  1266. #endif // MILLEN
  1267. ASSERT(Action == FORWARD);
  1268. if (BufferChanged) {
  1269. // if packet touched compute the new length: DataSize
  1270. DataLength = 0;
  1271. tmpRcvBuf = pRcvBuf;
  1272. while (tmpRcvBuf != NULL) {
  1273. ASSERT(tmpRcvBuf->ipr_buffer != NULL);
  1274. DataLength += tmpRcvBuf->ipr_size;
  1275. tmpRcvBuf = tmpRcvBuf->ipr_next;
  1276. }
  1277. // also make Header point to new buffer
  1278. Header = (IPHeader *) pRcvBuf->ipr_buffer;
  1279. HeaderLength = (Header->iph_verlen & 0xf) << 2;
  1280. }
  1281. DataLength -= HeaderLength; // decrement the header length
  1282. if (DestinationType == DEST_INVALID) { // Dest Addr changed by hook
  1283. // Can IPSEC changed iph_dest ???
  1284. DAddr = Header->iph_dest;
  1285. DstNTE = SrcNTE;
  1286. DestType = GetLocalNTE(DAddr, &DstNTE);
  1287. DestNTE = DstNTE;
  1288. }
  1289. if (DestType < DEST_REMOTE) {
  1290. // Check to see options
  1291. if (HeaderLength != sizeof(IPHeader)) {
  1292. // We have options
  1293. uchar NewDType;
  1294. NewDType = CheckLocalOptions(SrcNTE,
  1295. (IPHeader UNALIGNED *) Header,
  1296. OptInfo,
  1297. DestType,
  1298. NULL,
  1299. 0,
  1300. FALSE);
  1301. if (NewDType != DEST_LOCAL) {
  1302. if (NewDType == DEST_REMOTE) {
  1303. if (PromiscuousMode) {
  1304. if (FastPath) {
  1305. uchar *saveddata = pRcvBuf->ipr_buffer;
  1306. pRcvBuf->ipr_buffer += HeaderLength;
  1307. pRcvBuf->ipr_size -= HeaderLength;
  1308. DeliverToUser(SrcNTE, DestNTE,
  1309. (IPHeader UNALIGNED *) Header,
  1310. HeaderLength, pRcvBuf,
  1311. DataLength, OptInfo, NULL,
  1312. DestType);
  1313. // restore the buffer
  1314. pRcvBuf->ipr_buffer = saveddata;
  1315. pRcvBuf->ipr_size += HeaderLength;
  1316. } else {
  1317. uchar *saveddata = pRcvBuf->ipr_next->ipr_buffer;
  1318. DeliverToUser(SrcNTE, DestNTE,
  1319. (IPHeader UNALIGNED *) Header,
  1320. HeaderLength, pRcvBuf->ipr_next,
  1321. DataLength, OptInfo, NULL,
  1322. DestType);
  1323. // restore the buffers;
  1324. pRcvBuf->ipr_next->ipr_buffer = saveddata;
  1325. }
  1326. }
  1327. goto forward_local;
  1328. } else {
  1329. IPSInfo.ipsi_inhdrerrors++;
  1330. IPFreeBuff(pRcvBuf);
  1331. //CTEFreeMem(pBuff);
  1332. return; // Bad Options
  1333. }
  1334. } // NewDtype != LOCAL
  1335. } // Options present
  1336. } // DestType < DEST_REMOTE
  1337. else { // DestType >=DEST_REMOTE
  1338. if (PromiscuousMode) {
  1339. if (FastPath) {
  1340. uchar *saveddata = pRcvBuf->ipr_buffer;
  1341. pRcvBuf->ipr_buffer += HeaderLength;
  1342. pRcvBuf->ipr_size -= HeaderLength;
  1343. DeliverToUser(SrcNTE, DestNTE,
  1344. (IPHeader UNALIGNED *) Header, HeaderLength,
  1345. pRcvBuf, DataLength, OptInfo, NULL, DestType);
  1346. // restore the buffer
  1347. pRcvBuf->ipr_buffer = saveddata;
  1348. pRcvBuf->ipr_size += HeaderLength;
  1349. } else {
  1350. uchar *saveddata = pRcvBuf->ipr_next->ipr_buffer;
  1351. DeliverToUser(SrcNTE, DestNTE,
  1352. (IPHeader UNALIGNED *) Header, HeaderLength,
  1353. pRcvBuf->ipr_next, DataLength, OptInfo,
  1354. NULL, DestType);
  1355. // restore the buffers;
  1356. pRcvBuf->ipr_next->ipr_buffer = saveddata;
  1357. }
  1358. }
  1359. goto forward_local;
  1360. }
  1361. if (FastPath) {
  1362. uchar *saveddata = pRcvBuf->ipr_buffer;
  1363. pRcvBuf->ipr_buffer += HeaderLength;
  1364. pRcvBuf->ipr_size -= HeaderLength;
  1365. DeliverToUser(SrcNTE, DestNTE, (IPHeader UNALIGNED *) Header, HeaderLength,
  1366. pRcvBuf, DataLength, OptInfo, NULL, DestType);
  1367. // restore the buffer
  1368. pRcvBuf->ipr_buffer = saveddata;
  1369. pRcvBuf->ipr_size += HeaderLength;
  1370. } else {
  1371. uchar *saveddata = pRcvBuf->ipr_next->ipr_buffer;
  1372. DeliverToUser(
  1373. SrcNTE, DestNTE, (IPHeader UNALIGNED *) Header,
  1374. HeaderLength, pRcvBuf->ipr_next, DataLength,
  1375. OptInfo, NULL, DestType);
  1376. // restore the buffers;
  1377. pRcvBuf->ipr_next->ipr_buffer = saveddata;
  1378. }
  1379. if (IS_BCAST_DEST(DestType)) {
  1380. OneChunk = FALSE;
  1381. if (pRcvBuf->ipr_next == NULL) {
  1382. OneChunk = TRUE;
  1383. pBuff = pRcvBuf->ipr_buffer;
  1384. }else {
  1385. pBuff = ConvertIPRcvBufToFlatBuffer(
  1386. pRcvBuf, DataLength + HeaderLength);
  1387. if (!pBuff) {
  1388. IPSInfo.ipsi_indiscards++;
  1389. IPFreeBuff(pRcvBuf);
  1390. return;
  1391. }
  1392. }
  1393. if (!(pRcvBuf->ipr_flags & IPR_FLAG_LOOPBACK_PACKET)) {
  1394. IPForwardPkt(SrcNTE, (IPHeader UNALIGNED *) pBuff,
  1395. HeaderLength, pBuff + HeaderLength,
  1396. DataLength, NULL, 0, DestType, 0, NULL,
  1397. NULL, LinkCtxt);
  1398. }
  1399. if (!OneChunk) {
  1400. CTEFreeMem(pBuff); // free the flat buffer
  1401. }
  1402. }
  1403. IPFreeBuff(pRcvBuf);
  1404. //CTEFreeMem(pBuff); // free the flat buffer
  1405. return;
  1406. forward_local:
  1407. OneChunk = FALSE;
  1408. if (pRcvBuf->ipr_next == NULL) {
  1409. OneChunk = TRUE;
  1410. pBuff = pRcvBuf->ipr_buffer;
  1411. } else {
  1412. pBuff = ConvertIPRcvBufToFlatBuffer(pRcvBuf, DataLength + HeaderLength);
  1413. if (!pBuff) {
  1414. IPSInfo.ipsi_indiscards++;
  1415. IPFreeBuff(pRcvBuf);
  1416. return;
  1417. }
  1418. }
  1419. //
  1420. // If mdl in the packet is not changed and this is a simple
  1421. // packet with only one buffer then pass the packet, mdl and
  1422. // ClientCnt so that IPForwardPkt() can try to use super fast
  1423. // path.
  1424. //
  1425. if (!(pRcvBuf->ipr_flags & IPR_FLAG_LOOPBACK_PACKET)) {
  1426. if (OneChunk && pRcvBuf->ipr_pMdl &&
  1427. ((BufferChanged == 0) ||
  1428. (pRcvBuf->ipr_flags & IPR_FLAG_BUFFER_UNCHANGED))) {
  1429. uint MacHeaderSize = pRcvBuf->ipr_RcvOffset - HeaderLength;
  1430. IPForwardPkt(SrcNTE, (IPHeader UNALIGNED *) pBuff, HeaderLength,
  1431. pBuff + HeaderLength, DataLength, Packet, 0, DestType,
  1432. MacHeaderSize, pRcvBuf->ipr_pMdl,pRcvBuf->ipr_pClientCnt, LinkCtxt);
  1433. } else {
  1434. IPForwardPkt(SrcNTE, (IPHeader UNALIGNED *) pBuff, HeaderLength,
  1435. pBuff + HeaderLength, DataLength, NULL, 0, DestType,
  1436. 0, NULL, NULL, LinkCtxt);
  1437. }
  1438. }
  1439. if (!OneChunk) {
  1440. CTEFreeMem(pBuff); // free the flat buffer
  1441. }
  1442. IPFreeBuff(pRcvBuf);
  1443. return;
  1444. } else { // No Firewall
  1445. //
  1446. // Call into IPSEC so he can decrypt the data
  1447. //
  1448. if (IPSecHandlerPtr) {
  1449. //
  1450. // See if IPSEC is enabled, see if it needs to do anything with this
  1451. // packet.
  1452. //
  1453. FORWARD_ACTION Action;
  1454. ULONG ipsecByteCount = 0;
  1455. ULONG ipsecMTU = 0;
  1456. ULONG ipsecFlags = IPSEC_FLAG_INCOMING;
  1457. PNDIS_BUFFER newBuf = NULL;
  1458. if (SrcNTE == LoopNTE) {
  1459. ipsecFlags |= IPSEC_FLAG_LOOPBACK;
  1460. }
  1461. if (OptInfo->ioi_flags & IP_FLAG_SSRR) {
  1462. ipsecFlags |= IPSEC_FLAG_SSRR;
  1463. }
  1464. Action = (*IPSecHandlerPtr) (
  1465. (PUCHAR) Header,
  1466. (PVOID) Data,
  1467. SrcNTE->nte_if, // SrcIF
  1468. Packet,
  1469. &ipsecByteCount,
  1470. &ipsecMTU,
  1471. (PVOID *) &newBuf,
  1472. &ipsecFlags,
  1473. DestType);
  1474. if (Action != eFORWARD) {
  1475. IPSInfo.ipsi_indiscards++;
  1476. return;
  1477. } else {
  1478. //
  1479. // Update the data length if IPSEC changed it
  1480. // (like by removing the AH)
  1481. //
  1482. DataLength -= ipsecByteCount;
  1483. UpdateIPSecRcvBuf(Data, ipsecFlags);
  1484. }
  1485. }
  1486. // Call the filter hook if installed
  1487. if (RefPtrValid(&FilterRefPtr)) {
  1488. Interface *IF = SrcNTE->nte_if;
  1489. IPAddr LinkNextHop;
  1490. FORWARD_ACTION Action;
  1491. IPPacketFilterPtr FilterPtr;
  1492. if ((IF->if_flags & IF_FLAGS_P2MP) && LinkCtxt) {
  1493. LinkNextHop = LinkCtxt->link_NextHop;
  1494. } else {
  1495. LinkNextHop = NULL_IP_ADDR;
  1496. }
  1497. FilterPtr = AcquireRefPtr(&FilterRefPtr);
  1498. Action = (*FilterPtr) (Header,
  1499. Data->ipr_buffer,
  1500. Data->ipr_size,
  1501. IF->if_index,
  1502. INVALID_IF_INDEX,
  1503. LinkNextHop,
  1504. NULL_IP_ADDR);
  1505. ReleaseRefPtr(&FilterRefPtr);
  1506. if (Action != FORWARD) {
  1507. IPSInfo.ipsi_indiscards++;
  1508. return;
  1509. }
  1510. }
  1511. // Packet was local only: so even if promiscuous mode set just call
  1512. // delivertouser
  1513. DeliverToUser(SrcNTE, DestNTE, (IPHeader UNALIGNED *) Header,
  1514. HeaderLength, Data, DataLength, OptInfo, NULL, DestType);
  1515. if (IS_BCAST_DEST(DestType)) {
  1516. uchar *pBuff;
  1517. OneChunk = FALSE;
  1518. if (Data != NULL && !Data->ipr_next) {
  1519. OneChunk = TRUE;
  1520. pBuff = Data->ipr_buffer;
  1521. } else {
  1522. pBuff = ConvertIPRcvBufToFlatBuffer(Data, DataLength);
  1523. if (!pBuff) {
  1524. return;
  1525. }
  1526. }
  1527. if (!(Data->ipr_flags & IPR_FLAG_LOOPBACK_PACKET)) {
  1528. IPForwardPkt(SrcNTE, (IPHeader UNALIGNED *) Header, HeaderLength,
  1529. pBuff, DataLength, NULL, 0, DestType, 0, NULL, NULL,
  1530. LinkCtxt);
  1531. }
  1532. if (!OneChunk) {
  1533. CTEFreeMem(pBuff);
  1534. }
  1535. }
  1536. }
  1537. }
  1538. //* FreeRH - Free a reassembly header.
  1539. //
  1540. // Called when we need to free a reassembly header, either because of a
  1541. // timeout or because we're done with it.
  1542. //
  1543. // Input: RH - RH to be freed.
  1544. //
  1545. // Returns: Nothing.
  1546. //
  1547. void
  1548. FreeRH(ReassemblyHeader *RH)
  1549. {
  1550. RABufDesc *RBD, *TempRBD;
  1551. RBD = RH->rh_rbd;
  1552. if (IPSecHandlerPtr) {
  1553. IPFreeBuff((IPRcvBuf *) RBD);
  1554. } else {
  1555. while (RBD != NULL) {
  1556. TempRBD = RBD;
  1557. RBD = (RABufDesc *) RBD->rbd_buf.ipr_next;
  1558. CTEFreeMem(TempRBD);
  1559. }
  1560. }
  1561. CTEFreeMem(RH);
  1562. // decrement NumRH
  1563. CTEInterlockedDecrementLong(&NumRH);
  1564. }
  1565. //* ReassembleFragment - Put a fragment into the reassembly list.
  1566. //
  1567. // This routine is called once we've put a fragment into the proper buffer.
  1568. // We look for a reassembly header for the fragment. If we don't find one,
  1569. // we create one. Otherwise we search the reassembly list, and insert the
  1570. // datagram in it's proper place.
  1571. //
  1572. // Input: NTE - NTE to reassemble on.
  1573. // SrcNTE - NTE datagram arrived on.
  1574. // NewRBD - New RBD to be inserted.
  1575. // IPH - Pointer to header of datagram.
  1576. // HeaderSize - Size in bytes of header.
  1577. // DestType - Type of destination address.
  1578. //
  1579. // Returns: Nothing.
  1580. //
  1581. void
  1582. ReassembleFragment(NetTableEntry * NTE, NetTableEntry * SrcNTE, RABufDesc * NewRBD,
  1583. IPHeader UNALIGNED * IPH, uint HeaderSize, uchar DestType, LinkEntry * LinkCtxt)
  1584. {
  1585. ReassemblyHeader *RH, *PrevRH; // Current and previous reassembly headers.
  1586. RABufDesc *PrevRBD; // Previous RBD in reassembly header list.
  1587. RABufDesc *CurrentRBD;
  1588. ushort DataLength = (ushort) NewRBD->rbd_buf.ipr_size, DataOffset;
  1589. ushort Offset; // Offset of this fragment.
  1590. ushort NewOffset; // Offset we'll copy from after checking RBD list.
  1591. ushort NewEnd; // End offset of fragment, after trimming (if any).
  1592. // used by the firewall code
  1593. IPRcvBuf *pRcvBuf;
  1594. uint FirewallMode;
  1595. uint PromiscuousMode;
  1596. PromiscuousMode = SrcNTE->nte_if->if_promiscuousmode;
  1597. FirewallMode = ProcessFirewallQ();
  1598. // If this is a broadcast, go ahead and forward it now.
  1599. // if second condition is false then delivertouserex() will take care of
  1600. // this
  1601. if (IS_BCAST_DEST(DestType) &&
  1602. !(((IPSecHandlerPtr) && (RefPtrValid(&FilterRefPtr))) ||
  1603. (FirewallMode) || (PromiscuousMode))) {
  1604. IPForwardPkt(SrcNTE, IPH, HeaderSize, NewRBD->rbd_buf.ipr_buffer,
  1605. NewRBD->rbd_buf.ipr_size, NULL, 0, DestType, 0, NULL,
  1606. NULL, LinkCtxt);
  1607. }
  1608. if (NumRH > MaxRH) {
  1609. IPSInfo.ipsi_reasmfails++;
  1610. FragmentAttackDrops++;
  1611. CTEFreeMem(NewRBD);
  1612. return;
  1613. }
  1614. Offset = IPH->iph_offset & IP_OFFSET_MASK;
  1615. Offset = net_short(Offset) * 8;
  1616. if ((NumRH == MaxRH) && !Offset) {
  1617. IPSInfo.ipsi_reasmfails++;
  1618. CTEFreeMem(NewRBD);
  1619. return;
  1620. }
  1621. if ((ulong) (Offset + DataLength) > MAX_DATA_LENGTH) {
  1622. IPSInfo.ipsi_reasmfails++;
  1623. CTEFreeMem(NewRBD);
  1624. return;
  1625. }
  1626. // We've got the buffer we need. Now get the reassembly header, if there is one. If
  1627. // there isn't, create one.
  1628. CTEGetLockAtDPC(&NTE->nte_lock);
  1629. RH = FindRH(&PrevRH, NTE, IPH->iph_dest, IPH->iph_src, IPH->iph_id,
  1630. IPH->iph_protocol);
  1631. if (RH == (ReassemblyHeader *) NULL) { // Didn't find one, so create one.
  1632. ReassemblyHeader *NewRH;
  1633. CTEFreeLockFromDPC(&NTE->nte_lock);
  1634. RH = CTEAllocMemN(sizeof(ReassemblyHeader), 'diCT');
  1635. if (RH == (ReassemblyHeader *) NULL) { // Couldn't get a buffer.
  1636. IPSInfo.ipsi_reasmfails++;
  1637. CTEFreeMem(NewRBD);
  1638. return;
  1639. }
  1640. CTEInterlockedIncrementLong(&NumRH);
  1641. CTEGetLockAtDPC(&NTE->nte_lock);
  1642. // Need to look it up again - it could have changed during above call.
  1643. NewRH = FindRH(&PrevRH, NTE, IPH->iph_dest, IPH->iph_src, IPH->iph_id, IPH->iph_protocol);
  1644. if (NewRH != (ReassemblyHeader *) NULL) {
  1645. CTEFreeMem(RH);
  1646. RH = NewRH;
  1647. CTEInterlockedDecrementLong(&NumRH);
  1648. } else {
  1649. RH->rh_next = PrevRH->rh_next;
  1650. PrevRH->rh_next = RH;
  1651. // Initialize our new reassembly header.
  1652. RH->rh_dest = IPH->iph_dest;
  1653. RH->rh_src = IPH->iph_src;
  1654. RH->rh_id = IPH->iph_id;
  1655. RH->rh_protocol = IPH->iph_protocol;
  1656. //RH->rh_ttl = RATimeout;
  1657. RH->rh_ttl = MAX(RATimeout, MIN(120, IPH->iph_ttl) + 1);
  1658. RH->rh_numoverlaps = 0;
  1659. RH->rh_datasize = MAX_TOTAL_LENGTH; // Default datasize to maximum.
  1660. RH->rh_rbd = (RABufDesc *) NULL; // And nothing on chain.
  1661. RH->rh_datarcvd = 0; // Haven't received any data yet.
  1662. RH->rh_headersize = 0;
  1663. }
  1664. }
  1665. // When we reach here RH points to the reassembly header we want to use.
  1666. // and we hold locks on the NTE and the RH. If this is the first fragment
  1667. // we'll save the options and header information here.
  1668. if (Offset == 0) { // First fragment.
  1669. RH->rh_headersize = (ushort)HeaderSize;
  1670. RtlCopyMemory(RH->rh_header, IPH, HeaderSize + 8);
  1671. }
  1672. // If this is the last fragment, update the amount of data we expect to
  1673. // receive.
  1674. if (!(IPH->iph_offset & IP_MF_FLAG)) {
  1675. RH->rh_datasize = Offset + DataLength;
  1676. }
  1677. if (RH->rh_datasize < RH->rh_datarcvd ||
  1678. (RH->rh_datasize != MAX_TOTAL_LENGTH &&
  1679. (RH->rh_datasize + RH->rh_headersize) > MAX_TOTAL_LENGTH)) {
  1680. // random packets. drop!
  1681. CTEFreeMem(NewRBD);
  1682. PrevRH->rh_next = RH->rh_next;
  1683. FreeRH(RH);
  1684. CTEFreeLockFromDPC(&NTE->nte_lock);
  1685. return;
  1686. }
  1687. // Update the TTL value with the maximum of the current TTL and the
  1688. // incoming TTL (+1, to deal with rounding errors).
  1689. // Following is commented out to protect against fragmentation attack
  1690. // Default TTL now used is 120 seconds now, used only for the first header
  1691. // RH->rh_ttl = MAX(RH->rh_ttl, MIN(254, IPH->iph_ttl) + 1);
  1692. // Now we need to see where in the RBD list to put this.
  1693. //
  1694. // The idea is to go through the list of RBDs one at a time. The RBD
  1695. // currently being examined is CurrentRBD. If the start offset of the new
  1696. // fragment is less than (i.e. in front of) the offset of CurrentRBD, we
  1697. // need to insert the NewRBD in front of the CurrentRBD. If this is the
  1698. // case we need to check and see if the
  1699. // end of the new fragment overlaps some or all of the fragment described by
  1700. // CurrentRBD, and possibly subsequent fragment. If it overlaps part of a
  1701. // fragment we'll adjust our end down to be in front of the existing
  1702. // fragment. If it overlaps all of the fragment we'll free the old fragment.
  1703. //
  1704. // If the new fragment does not start in front of the current fragment
  1705. // we'll check to see if it starts somewhere in the middle of the current
  1706. // fragment. If this isn't the case, we move on the the next fragment. If
  1707. // this is the case, we check to see if the current fragment completely // covers the new fragment. If not we
  1708. // move our start up and continue with the next fragment.
  1709. //
  1710. NewOffset = Offset;
  1711. NewEnd = Offset + DataLength - 1;
  1712. PrevRBD = STRUCT_OF(RABufDesc, STRUCT_OF(IPRcvBuf, &RH->rh_rbd, ipr_next), rbd_buf);
  1713. CurrentRBD = RH->rh_rbd;
  1714. for (; CurrentRBD != NULL; PrevRBD = CurrentRBD, CurrentRBD = (RABufDesc *) CurrentRBD->rbd_buf.ipr_next) {
  1715. // See if it starts in front of this fragment.
  1716. if (NewOffset < CurrentRBD->rbd_start) {
  1717. // It does start in front. Check to see if there's any overlap.
  1718. if (NewEnd < CurrentRBD->rbd_start)
  1719. break; // No overlap, so get out.
  1720. else {
  1721. //
  1722. // It does overlap. While we have overlap, walk down the list
  1723. // looking for RBDs we overlap completely. If we find one,
  1724. // put it on our deletion list. If we have overlap but not
  1725. // complete overlap, move our end down if front of the
  1726. // fragment we overlap.
  1727. //
  1728. do {
  1729. RH->rh_numoverlaps++;
  1730. if (RH->rh_numoverlaps >= MaxOverlap) {
  1731. //Looks like we are being attacked.
  1732. //Just drop this whole datagram.
  1733. NewRBD->rbd_buf.ipr_next = (IPRcvBuf *) CurrentRBD;
  1734. PrevRBD->rbd_buf.ipr_next = &NewRBD->rbd_buf;
  1735. PrevRH->rh_next = RH->rh_next;
  1736. FreeRH(RH);
  1737. FragmentAttackDrops++;
  1738. CTEFreeLockFromDPC(&NTE->nte_lock);
  1739. return;
  1740. }
  1741. if (NewEnd > CurrentRBD->rbd_end) { //overlaps completely.
  1742. RABufDesc *TempRBD;
  1743. RH->rh_datarcvd = RH->rh_datarcvd -
  1744. (ushort) (CurrentRBD->rbd_buf.ipr_size);
  1745. TempRBD = CurrentRBD;
  1746. CurrentRBD = (RABufDesc *) CurrentRBD->rbd_buf.ipr_next;
  1747. CTEFreeMem(TempRBD);
  1748. } else { //partial ovelap.
  1749. if (NewOffset < CurrentRBD->rbd_start) {
  1750. NewEnd = CurrentRBD->rbd_start - 1;
  1751. } else {
  1752. // Looks like we are being attacked.
  1753. // Just drop this whole datagram.
  1754. NewRBD->rbd_buf.ipr_next = (IPRcvBuf *) CurrentRBD;
  1755. PrevRBD->rbd_buf.ipr_next = &NewRBD->rbd_buf;
  1756. PrevRH->rh_next = RH->rh_next;
  1757. FreeRH(RH);
  1758. CTEFreeLockFromDPC(&NTE->nte_lock);
  1759. return;
  1760. }
  1761. }
  1762. // Update of NewEnd will force us out of loop.
  1763. } while (CurrentRBD != NULL && NewEnd >= CurrentRBD->rbd_start);
  1764. break;
  1765. }
  1766. } else {
  1767. // This fragment doesn't go in front of the current RBD. See if it
  1768. // is entirely beyond the end of the current fragment. If it is,
  1769. // just continue. Otherwise see if the current fragment
  1770. // completely subsumes us. If it does, get out, otherwise update
  1771. // our start offset and continue.
  1772. if (NewOffset > CurrentRBD->rbd_end)
  1773. continue; // No overlap at all.
  1774. else {
  1775. RH->rh_numoverlaps++;
  1776. if (RH->rh_numoverlaps >= MaxOverlap) {
  1777. //Looks like we are being attacked.
  1778. //Just drop this whole datagram.
  1779. NewRBD->rbd_buf.ipr_next = (IPRcvBuf *) CurrentRBD;
  1780. PrevRBD->rbd_buf.ipr_next = &NewRBD->rbd_buf;
  1781. PrevRH->rh_next = RH->rh_next;
  1782. FreeRH(RH);
  1783. FragmentAttackDrops++;
  1784. CTEFreeLockFromDPC(&NTE->nte_lock);
  1785. return;
  1786. }
  1787. if (NewEnd <= CurrentRBD->rbd_end) {
  1788. //
  1789. // The current fragment overlaps the new fragment
  1790. // totally. Set our offsets so that we'll skip the copy
  1791. // below.
  1792. NewEnd = NewOffset - 1;
  1793. break;
  1794. } else // Only partial overlap.
  1795. NewOffset = CurrentRBD->rbd_end + 1;
  1796. }
  1797. }
  1798. } // End of for loop.
  1799. // Adjust the length and offset fields in the new RBD.
  1800. // If we've trimmed all the data away, ignore this fragment.
  1801. DataLength = NewEnd - NewOffset + 1;
  1802. DataOffset = NewOffset - Offset;
  1803. if (!DataLength) {
  1804. CTEFreeMem(NewRBD);
  1805. CTEFreeLockFromDPC(&NTE->nte_lock);
  1806. return;
  1807. }
  1808. // Link him in chain.
  1809. NewRBD->rbd_buf.ipr_size = (uint) DataLength;
  1810. NewRBD->rbd_end = NewEnd;
  1811. NewRBD->rbd_start = (ushort) NewOffset;
  1812. RH->rh_datarcvd = RH->rh_datarcvd + (ushort) DataLength;
  1813. NewRBD->rbd_buf.ipr_buffer += DataOffset;
  1814. NewRBD->rbd_buf.ipr_next = (IPRcvBuf *) CurrentRBD;
  1815. NewRBD->rbd_buf.ipr_owner = IPR_OWNER_IP;
  1816. PrevRBD->rbd_buf.ipr_next = &NewRBD->rbd_buf;
  1817. // If we've received all the data, deliver it to the user.
  1818. // Only if header size is valid deliver to the user
  1819. // BUG #NTQFE 65742
  1820. if (RH->rh_datarcvd == RH->rh_datasize && RH->rh_headersize) { // We have it all.
  1821. IPOptInfo OptInfo;
  1822. IPHeader *Header;
  1823. IPRcvBuf *FirstBuf;
  1824. ulong Checksum;
  1825. PrevRH->rh_next = RH->rh_next;
  1826. CTEFreeLockFromDPC(&NTE->nte_lock);
  1827. Header = (IPHeader *) RH->rh_header;
  1828. OptInfo.ioi_ttl = Header->iph_ttl;
  1829. OptInfo.ioi_tos = Header->iph_tos;
  1830. OptInfo.ioi_flags = 0; // Flags must be 0 - DF can't be set,
  1831. // this was reassembled.
  1832. if (RH->rh_headersize != sizeof(IPHeader)) { // We had options.
  1833. OptInfo.ioi_options = (uchar *) (Header + 1);
  1834. OptInfo.ioi_optlength = (uchar) (RH->rh_headersize - sizeof(IPHeader));
  1835. } else {
  1836. OptInfo.ioi_options = (uchar *) NULL;
  1837. OptInfo.ioi_optlength = 0;
  1838. }
  1839. //
  1840. // update the indicated header len to the total len; earlier we passed in
  1841. // just the first fragment's length.
  1842. // also update the 'MF' bit in the flags field.
  1843. //
  1844. // in the process update the header-checksum,
  1845. // by first adding the negation of the original length and flags,
  1846. // and then adding the new length and flags.
  1847. //
  1848. // extract the original checksum
  1849. Checksum = (ushort) ~ Header->iph_xsum;
  1850. // update the header length
  1851. Checksum += (ushort) ~ Header->iph_length;
  1852. Header->iph_length = net_short(RH->rh_datasize + RH->rh_headersize);
  1853. Checksum += (ushort) Header->iph_length;
  1854. // update the 'MF' flag if set
  1855. if (Header->iph_offset & IP_MF_FLAG) {
  1856. Checksum += (ushort) ~ IP_MF_FLAG;
  1857. Header->iph_offset &= ~IP_MF_FLAG;
  1858. }
  1859. // insert the new checksum
  1860. Checksum = (ushort) Checksum + (ushort) (Checksum >> 16);
  1861. Checksum += Checksum >> 16;
  1862. Header->iph_xsum = (ushort) ~ Checksum;
  1863. // Make sure that the first buffer contains enough data.
  1864. FirstBuf = (IPRcvBuf *) RH->rh_rbd;
  1865. // Make sure that this can hold MIN_FIRST_SIZE
  1866. // Else treat it as attack
  1867. if (RH->rh_rbd->rbd_AllocSize < MIN_FIRST_SIZE) {
  1868. //Attack???
  1869. FreeRH(RH);
  1870. return;
  1871. }
  1872. while (FirstBuf->ipr_size < MIN_FIRST_SIZE) {
  1873. IPRcvBuf *NextBuf = FirstBuf->ipr_next;
  1874. uint CopyLength;
  1875. if (NextBuf == NULL)
  1876. break;
  1877. CopyLength = MIN(MIN_FIRST_SIZE - FirstBuf->ipr_size,
  1878. NextBuf->ipr_size);
  1879. RtlCopyMemory(FirstBuf->ipr_buffer + FirstBuf->ipr_size,
  1880. NextBuf->ipr_buffer, CopyLength);
  1881. FirstBuf->ipr_size += CopyLength;
  1882. NextBuf->ipr_buffer += CopyLength;
  1883. NextBuf->ipr_size -= CopyLength;
  1884. if (NextBuf->ipr_size == 0) {
  1885. FirstBuf->ipr_next = NextBuf->ipr_next;
  1886. CTEFreeMem(NextBuf);
  1887. }
  1888. }
  1889. IPSInfo.ipsi_reasmoks++;
  1890. if (((IPSecHandlerPtr) && (RefPtrValid(&FilterRefPtr))) ||
  1891. (FirewallMode) || (PromiscuousMode) ) {
  1892. uint DataSize;
  1893. DataSize = RH->rh_datasize;
  1894. if (FirewallMode) {
  1895. // Attach header to pass to Firewall hook
  1896. pRcvBuf = (IPRcvBuf *) CTEAllocMemN(sizeof(IPRcvBuf), 'eiCT');
  1897. if (!pRcvBuf) {
  1898. FreeRH(RH);
  1899. return;
  1900. }
  1901. pRcvBuf->ipr_buffer = (uchar *) RH->rh_header;
  1902. pRcvBuf->ipr_size = RH->rh_headersize;
  1903. pRcvBuf->ipr_owner = IPR_OWNER_IP;
  1904. pRcvBuf->ipr_next = FirstBuf;
  1905. pRcvBuf->ipr_flags = 0;
  1906. DataSize += RH->rh_headersize;
  1907. } else {
  1908. pRcvBuf = FirstBuf;
  1909. }
  1910. DeliverToUserEx(SrcNTE, NTE, Header, RH->rh_headersize, pRcvBuf,
  1911. DataSize, &OptInfo, NULL, DestType, LinkCtxt);
  1912. if (FirewallMode) {
  1913. // RH chain is already freed.
  1914. CTEFreeMem(RH);
  1915. CTEInterlockedDecrementLong(&NumRH);
  1916. } else {
  1917. FreeRH(RH);
  1918. }
  1919. } else { // Normal Path
  1920. DeliverToUser(SrcNTE, NTE, Header, RH->rh_headersize, FirstBuf,
  1921. RH->rh_datasize, &OptInfo, NULL, DestType);
  1922. FreeRH(RH);
  1923. }
  1924. } else
  1925. CTEFreeLockFromDPC(&NTE->nte_lock);
  1926. }
  1927. //* RATDComplete - Completion routing for a reassembly transfer data.
  1928. //
  1929. // This is the completion handle for TDs invoked because we are reassembling
  1930. // a fragment.
  1931. //
  1932. // Input: NetContext - Ptr to the net table entry on which we received
  1933. // this.
  1934. // Packet - Packet we received into.
  1935. // Status - Final status of copy.
  1936. // DataSize - Size in bytes of data transferred.
  1937. //
  1938. // Returns: Nothing
  1939. //
  1940. void
  1941. RATDComplete(void *NetContext, PNDIS_PACKET Packet, NDIS_STATUS Status, uint DataSize)
  1942. {
  1943. NetTableEntry *NTE = (NetTableEntry *) NetContext;
  1944. Interface *SrcIF;
  1945. TDContext *Context = (TDContext *) Packet->ProtocolReserved;
  1946. PNDIS_BUFFER Buffer;
  1947. if (Status == NDIS_STATUS_SUCCESS) {
  1948. Context->tdc_rbd->rbd_buf.ipr_size = DataSize;
  1949. ReassembleFragment(Context->tdc_nte, NTE, Context->tdc_rbd,
  1950. (IPHeader *) Context->tdc_header, Context->tdc_hlength, Context->tdc_dtype, NULL);
  1951. }
  1952. NdisUnchainBufferAtFront(Packet, &Buffer);
  1953. NdisFreeBuffer(Buffer);
  1954. Context->tdc_common.pc_flags &= ~PACKET_FLAG_RA;
  1955. SrcIF = NTE->nte_if;
  1956. CTEGetLockAtDPC(&SrcIF->if_lock);
  1957. Context->tdc_common.pc_link = SrcIF->if_tdpacket;
  1958. SrcIF->if_tdpacket = Packet;
  1959. CTEFreeLockFromDPC(&SrcIF->if_lock);
  1960. return;
  1961. }
  1962. //* IPReassemble - Reassemble an incoming datagram.
  1963. //
  1964. // Called when we receive an incoming fragment. The first thing we do is
  1965. // get a buffer to put the fragment in. If we can't we'll exit. Then we
  1966. // copy the data, either via transfer data or directly if it all fits.
  1967. //
  1968. // Input: SrcNTE - Pointer to NTE that received the datagram.
  1969. // NTE - Pointer to NTE on which to reassemble.
  1970. // IPH - Pointer to header of packet.
  1971. // HeaderSize - Size in bytes of header.
  1972. // Data - Pointer to data part of fragment.
  1973. // BufferLengt - Length in bytes of user data available in the
  1974. // buffer.
  1975. // DataLength - Length in bytes of the (upper-layer) data.
  1976. // DestType - Type of destination
  1977. // LContext1, LContext2 - Link layer context values.
  1978. //
  1979. // Returns: Nothing.
  1980. //
  1981. void
  1982. IPReassemble(NetTableEntry * SrcNTE, NetTableEntry * NTE, IPHeader UNALIGNED * IPH,
  1983. uint HeaderSize,
  1984. uchar * Data, uint BufferLength, uint DataLength, uchar DestType, NDIS_HANDLE LContext1,
  1985. uint LContext2, LinkEntry * LinkCtxt)
  1986. {
  1987. Interface *RcvIF;
  1988. PNDIS_PACKET TDPacket; // NDIS packet used for TD.
  1989. TDContext *TDC = (TDContext *) NULL; // Transfer data context.
  1990. NDIS_STATUS Status;
  1991. PNDIS_BUFFER Buffer;
  1992. RABufDesc *NewRBD; // Pointer to new RBD to hold
  1993. // arriving fragment.
  1994. uint AllocSize;
  1995. IPSInfo.ipsi_reasmreqds++;
  1996. //
  1997. // Drop invalid length fragments.
  1998. // We expect at least 8 byte len payload
  1999. // in fragments except for the last one.
  2000. //
  2001. if ((DataLength == 0) ||
  2002. ((IPH->iph_offset & IP_MF_FLAG) && DataLength < 8)) {
  2003. return;
  2004. }
  2005. //
  2006. // First, get a new RBD to hold the arriving fragment. If we can't,
  2007. // then just skip the rest. The RBD has the buffer implicitly at the end
  2008. // of it. The buffer for the first fragment must be at least
  2009. // MIN_FIRST_SIZE bytes.
  2010. //
  2011. if ((IPH->iph_offset & IP_OFFSET_MASK) == 0) {
  2012. AllocSize = MAX(MIN_FIRST_SIZE, DataLength);
  2013. } else
  2014. AllocSize = DataLength;
  2015. NewRBD = CTEAllocMemN(sizeof(RABufDesc) + AllocSize, 'fiCT');
  2016. if (NewRBD != (RABufDesc *) NULL) {
  2017. NewRBD->rbd_buf.ipr_buffer = (uchar *) (NewRBD + 1);
  2018. NewRBD->rbd_buf.ipr_size = DataLength;
  2019. NewRBD->rbd_buf.ipr_owner = IPR_OWNER_IP;
  2020. NewRBD->rbd_buf.ipr_flags = 0;
  2021. NewRBD->rbd_AllocSize = AllocSize;
  2022. NewRBD->rbd_buf.ipr_pMdl = NULL;
  2023. NewRBD->rbd_buf.ipr_pClientCnt = NULL;
  2024. //
  2025. // Copy the data into the buffer. If we need to call transfer data
  2026. // do so now.
  2027. //
  2028. if (DataLength > BufferLength) { // Need to call transfer data.
  2029. NdisAllocateBuffer(&Status, &Buffer, BufferPool, NewRBD + 1, DataLength);
  2030. if (Status != NDIS_STATUS_SUCCESS) {
  2031. IPSInfo.ipsi_reasmfails++;
  2032. CTEFreeMem(NewRBD);
  2033. return;
  2034. }
  2035. // Now get a packet for transferring the frame.
  2036. RcvIF = SrcNTE->nte_if;
  2037. CTEGetLockAtDPC(&RcvIF->if_lock);
  2038. TDPacket = RcvIF->if_tdpacket;
  2039. if (TDPacket != (PNDIS_PACKET) NULL) {
  2040. TDC = (TDContext *) TDPacket->ProtocolReserved;
  2041. RcvIF->if_tdpacket = TDC->tdc_common.pc_link;
  2042. CTEFreeLockFromDPC(&RcvIF->if_lock);
  2043. TDC->tdc_common.pc_flags |= PACKET_FLAG_RA;
  2044. TDC->tdc_nte = NTE;
  2045. TDC->tdc_dtype = DestType;
  2046. TDC->tdc_hlength = (uchar) HeaderSize;
  2047. TDC->tdc_rbd = NewRBD;
  2048. RtlCopyMemory(TDC->tdc_header, IPH, HeaderSize + 8);
  2049. NdisChainBufferAtFront(TDPacket, Buffer);
  2050. Status = (*(RcvIF->if_transfer)) (RcvIF->if_lcontext,
  2051. LContext1, LContext2, HeaderSize,
  2052. DataLength, TDPacket, &DataLength);
  2053. if (Status != NDIS_STATUS_PENDING)
  2054. RATDComplete(SrcNTE, TDPacket, Status, DataLength);
  2055. else
  2056. return;
  2057. } else { // Couldn't get a TD packet.
  2058. CTEFreeLockFromDPC(&RcvIF->if_lock);
  2059. CTEFreeMem(NewRBD);
  2060. IPSInfo.ipsi_reasmfails++;
  2061. return;
  2062. }
  2063. } else { // It all fits, copy it.
  2064. RtlCopyMemory(NewRBD + 1, Data, DataLength);
  2065. ReassembleFragment(NTE, SrcNTE, NewRBD, IPH, HeaderSize, DestType, LinkCtxt);
  2066. }
  2067. } else {
  2068. IPSInfo.ipsi_reasmfails++;
  2069. }
  2070. }
  2071. //* CheckLocalOptions - Check the options received with a packet.
  2072. //
  2073. // A routine called when we've received a packet for this host and want to
  2074. // examine it for options. We process the options, and return TRUE or FALSE
  2075. // depending on whether or not it's for us.
  2076. //
  2077. // Input: SrcNTE - Pointer to NTE this came in on.
  2078. // Header - Pointer to incoming header.
  2079. // OptInfo - Place to put opt info.
  2080. // DestType - Type of incoming packet.
  2081. //
  2082. // Returns: DestType - Local or remote.
  2083. //
  2084. uchar
  2085. CheckLocalOptions(NetTableEntry * SrcNTE, IPHeader UNALIGNED * Header,
  2086. IPOptInfo * OptInfo, uchar DestType, uchar* Data,
  2087. uint DataSize, BOOLEAN FilterOnDrop)
  2088. {
  2089. uint HeaderLength; // Length in bytes of header.
  2090. OptIndex Index;
  2091. uchar ErrIndex;
  2092. HeaderLength = (Header->iph_verlen & (uchar) ~ IP_VER_FLAG) << 2;
  2093. ASSERT(HeaderLength > sizeof(IPHeader));
  2094. OptInfo->ioi_options = (uchar *) (Header + 1);
  2095. OptInfo->ioi_optlength = (uchar) (HeaderLength - sizeof(IPHeader));
  2096. // We have options of some sort. The packet may or may not be bound for us.
  2097. Index.oi_srindex = MAX_OPT_SIZE;
  2098. if ((ErrIndex = ParseRcvdOptions(OptInfo, &Index)) < MAX_OPT_SIZE) {
  2099. if (!FilterOnDrop || !RefPtrValid(&FilterRefPtr) ||
  2100. NotifyFilterOfDiscard(SrcNTE, Header, Data, DataSize)) {
  2101. SendICMPErr(SrcNTE->nte_addr, Header, ICMP_PARAM_PROBLEM, PTR_VALID,
  2102. ((ulong) ErrIndex + sizeof(IPHeader)), 0);
  2103. }
  2104. return DEST_INVALID; // Parameter error.
  2105. }
  2106. //
  2107. // If there's no source route, or if the destination is a broadcast, we'll
  2108. // take it. If it is a broadcast DeliverToUser will forward it when it's
  2109. // done, and the forwarding code will reprocess the options.
  2110. //
  2111. if (Index.oi_srindex == MAX_OPT_SIZE || IS_BCAST_DEST(DestType))
  2112. return DEST_LOCAL;
  2113. else
  2114. return DEST_REMOTE;
  2115. }
  2116. //* TDUserRcv - Completion routing for a user transfer data.
  2117. //
  2118. // This is the completion handle for TDs invoked because we need to give
  2119. // data to a upper layer client. All we really do is call the upper layer
  2120. // handler with the data.
  2121. //
  2122. // Input: NetContext - Pointer to the net table entry on which we
  2123. // received this.
  2124. // Packet - Packet we received into.
  2125. // Status - Final status of copy.
  2126. // DataSize - Size in bytes of data transferred.
  2127. //
  2128. // Returns: Nothing
  2129. //
  2130. void
  2131. TDUserRcv(void *NetContext, PNDIS_PACKET Packet, NDIS_STATUS Status,
  2132. uint DataSize)
  2133. {
  2134. NetTableEntry *NTE = (NetTableEntry *) NetContext;
  2135. Interface *SrcIF;
  2136. TDContext *Context = (TDContext *) Packet->ProtocolReserved;
  2137. uchar DestType;
  2138. IPRcvBuf RcvBuf;
  2139. IPOptInfo OptInfo;
  2140. IPHeader *Header;
  2141. uint PromiscuousMode = 0;
  2142. uint FirewallMode = 0;
  2143. if (NTE->nte_flags & NTE_VALID) {
  2144. FirewallMode = ProcessFirewallQ();
  2145. PromiscuousMode = NTE->nte_if->if_promiscuousmode;
  2146. }
  2147. if (Status == NDIS_STATUS_SUCCESS) {
  2148. Header = (IPHeader *) Context->tdc_header;
  2149. OptInfo.ioi_ttl = Header->iph_ttl;
  2150. OptInfo.ioi_tos = Header->iph_tos;
  2151. OptInfo.ioi_flags = (uchar) ((net_short(Header->iph_offset) >> 13) & IP_FLAG_DF);
  2152. if (Context->tdc_hlength != sizeof(IPHeader)) {
  2153. OptInfo.ioi_options = (uchar *) (Header + 1);
  2154. OptInfo.ioi_optlength = Context->tdc_hlength - sizeof(IPHeader);
  2155. } else {
  2156. OptInfo.ioi_options = (uchar *) NULL;
  2157. OptInfo.ioi_optlength = 0;
  2158. }
  2159. DestType = Context->tdc_dtype;
  2160. RcvBuf.ipr_next = NULL;
  2161. RcvBuf.ipr_owner = IPR_OWNER_STACK;
  2162. RcvBuf.ipr_buffer = (uchar *) Context->tdc_buffer;
  2163. RcvBuf.ipr_size = DataSize;
  2164. RcvBuf.ipr_flags = 0;
  2165. RcvBuf.ipr_pMdl = NULL;
  2166. RcvBuf.ipr_pClientCnt = NULL;
  2167. if (((IPSecHandlerPtr) && (RefPtrValid(&FilterRefPtr))) ||
  2168. (FirewallMode) || (PromiscuousMode)) {
  2169. if (FirewallMode) {
  2170. // attach the header and allocate pRcvBuf on a heap, we free it if firewall is present
  2171. IPRcvBuf *pRcvBuf;
  2172. // attach the header
  2173. pRcvBuf = (IPRcvBuf *) CTEAllocMemN(sizeof(IPRcvBuf), 'giCT');
  2174. if (!pRcvBuf) {
  2175. return;
  2176. }
  2177. pRcvBuf->ipr_owner = IPR_OWNER_IP;
  2178. pRcvBuf->ipr_buffer = (uchar *) Header;
  2179. pRcvBuf->ipr_size = Context->tdc_hlength;
  2180. pRcvBuf->ipr_pMdl = NULL;
  2181. pRcvBuf->ipr_pClientCnt = NULL;
  2182. pRcvBuf->ipr_flags = 0;
  2183. // attach the data
  2184. pRcvBuf->ipr_next = (IPRcvBuf *) CTEAllocMemN(sizeof(IPRcvBuf), 'hiCT');
  2185. if (!pRcvBuf->ipr_next) {
  2186. CTEFreeMem(pRcvBuf);
  2187. return;
  2188. }
  2189. pRcvBuf->ipr_next->ipr_owner = IPR_OWNER_IP;
  2190. pRcvBuf->ipr_next->ipr_buffer = (uchar *) Context->tdc_buffer;
  2191. pRcvBuf->ipr_next->ipr_size = DataSize;
  2192. pRcvBuf->ipr_next->ipr_pMdl = NULL;
  2193. pRcvBuf->ipr_next->ipr_pClientCnt = NULL;
  2194. pRcvBuf->ipr_next->ipr_next = NULL;
  2195. pRcvBuf->ipr_next->ipr_flags = 0;
  2196. DataSize += Context->tdc_hlength;
  2197. DeliverToUserEx(NTE, Context->tdc_nte, Header, Context->tdc_hlength,
  2198. pRcvBuf, DataSize, &OptInfo, Packet, DestType, NULL);
  2199. } else {
  2200. DeliverToUserEx(NTE, Context->tdc_nte, Header, Context->tdc_hlength,
  2201. &RcvBuf, DataSize, &OptInfo, Packet, DestType, NULL);
  2202. }
  2203. } else {
  2204. DeliverToUser(NTE, Context->tdc_nte, Header, Context->tdc_hlength,
  2205. &RcvBuf, DataSize, &OptInfo, Packet, DestType);
  2206. // If it's a broadcast packet forward it on.
  2207. if (IS_BCAST_DEST(DestType))
  2208. IPForwardPkt(NTE, Header, Context->tdc_hlength, RcvBuf.ipr_buffer, DataSize,
  2209. NULL, 0, DestType, 0, NULL, NULL, NULL);
  2210. }
  2211. }
  2212. SrcIF = NTE->nte_if;
  2213. CTEGetLockAtDPC(&SrcIF->if_lock);
  2214. Context->tdc_common.pc_link = SrcIF->if_tdpacket;
  2215. SrcIF->if_tdpacket = Packet;
  2216. CTEFreeLockFromDPC(&SrcIF->if_lock);
  2217. }
  2218. void
  2219. IPInjectPkt(FORWARD_ACTION Action, void *SavedContext, uint SavedContextLength,
  2220. struct IPHeader UNALIGNED *IPH, struct IPRcvBuf *DataChain)
  2221. {
  2222. char *Data;
  2223. char *PreservedData;
  2224. uint DataSize;
  2225. PFIREWALL_CONTEXT_T pFirCtx = (PFIREWALL_CONTEXT_T) SavedContext;
  2226. NetTableEntry *NTE = pFirCtx->NTE; // Local NTE received on
  2227. LinkEntry *LinkCtxt = pFirCtx->LinkCtxt; // Local NTE received on
  2228. NetTableEntry *DestNTE; // NTE to receive on.
  2229. IPAddr DAddr; // Dest. IP addr. of received packet.
  2230. uint HeaderLength; // Size in bytes of received header.
  2231. uint IPDataLength; // Length in bytes of IP (including UL) data in packet.
  2232. IPOptInfo OptInfo; // Incoming header information.
  2233. uchar DestType; // Type (LOCAL, REMOTE, SR) of Daddr.
  2234. IPRcvBuf RcvBuf;
  2235. IPRcvBuf *tmpRcvBuf;
  2236. ulong Offset;
  2237. KIRQL OldIrql;
  2238. UNREFERENCED_PARAMETER(SavedContextLength);
  2239. //
  2240. // One can not inject a packet that was being transmitted earlier
  2241. //
  2242. ASSERT(pFirCtx->Direction == IP_RECEIVE);
  2243. if (Action == ICMP_ON_DROP) {
  2244. // send an ICMP message ?????
  2245. return;
  2246. }
  2247. ASSERT(Action == FORWARD);
  2248. DataSize = 0;
  2249. tmpRcvBuf = DataChain;
  2250. while (tmpRcvBuf != NULL) {
  2251. ASSERT(tmpRcvBuf->ipr_buffer != NULL);
  2252. DataSize += tmpRcvBuf->ipr_size;
  2253. tmpRcvBuf = tmpRcvBuf->ipr_next;
  2254. }
  2255. Data = (char *) CTEAllocMemN(DataSize, 'iiCT');
  2256. if (Data == NULL) {
  2257. return;
  2258. }
  2259. tmpRcvBuf = DataChain;
  2260. Offset = 0;
  2261. while (tmpRcvBuf != NULL) {
  2262. ASSERT(tmpRcvBuf->ipr_buffer != NULL);
  2263. #if DBG_VALIDITY_CHECK
  2264. if (Offset + tmpRcvBuf->ipr_size > DataSize) {
  2265. DbgPrint("Offset %d: tmpRcvBuf->ipr_size %d: DataSize %d ::::\n",
  2266. Offset, tmpRcvBuf->ipr_size, DataSize);
  2267. DbgBreakPoint();
  2268. }
  2269. #endif
  2270. RtlCopyMemory(Data + Offset, tmpRcvBuf->ipr_buffer, tmpRcvBuf->ipr_size);
  2271. Offset += tmpRcvBuf->ipr_size;
  2272. tmpRcvBuf = tmpRcvBuf->ipr_next;
  2273. }
  2274. PreservedData = Data;
  2275. // free the data chain
  2276. // IPFreeBuff(pContextInfo->DataChain);
  2277. IPH = (IPHeader UNALIGNED *) Data;
  2278. // Make sure we actually have data.
  2279. if (DataSize) {
  2280. // Check the header length, the xsum and the version. If any of these
  2281. // checks fail silently discard the packet.
  2282. HeaderLength = ((IPH->iph_verlen & (uchar) ~ IP_VER_FLAG) << 2);
  2283. if (HeaderLength >= sizeof(IPHeader) && HeaderLength <= DataSize) {
  2284. // Check the version, and sanity check the total length.
  2285. IPDataLength = (uint) net_short(IPH->iph_length);
  2286. if ((IPH->iph_verlen & IP_VER_FLAG) == IP_VERSION &&
  2287. IPDataLength > sizeof(IPHeader)) {
  2288. IPDataLength -= HeaderLength;
  2289. Data = (char *) Data + HeaderLength;
  2290. DataSize -= HeaderLength;
  2291. // IPDataLength should be equal to DataSize
  2292. ASSERT(IPDataLength == DataSize);
  2293. DAddr = IPH->iph_dest;
  2294. DestNTE = NTE;
  2295. // Find local NTE, if any.
  2296. DestType = GetLocalNTE(DAddr, &DestNTE);
  2297. OptInfo.ioi_ttl = IPH->iph_ttl;
  2298. OptInfo.ioi_tos = IPH->iph_tos;
  2299. OptInfo.ioi_flags = (uchar) ((net_short(IPH->iph_offset) >> 13) &
  2300. IP_FLAG_DF);
  2301. OptInfo.ioi_options = (uchar *) NULL;
  2302. OptInfo.ioi_optlength = 0;
  2303. if ((DestType < DEST_REMOTE)) {
  2304. // It's either local or some sort of broadcast.
  2305. // The data probably belongs at this station. If there
  2306. // aren't any options, it definetly belongs here, and we'll
  2307. // dispatch it either to our reasssmbly code or to the
  2308. // deliver to user code. If there are options, we'll check
  2309. // them and then either handle the packet locally or pass it
  2310. // to our forwarding code.
  2311. if (HeaderLength != sizeof(IPHeader)) {
  2312. // We have options.
  2313. uchar NewDType;
  2314. NewDType = CheckLocalOptions(NTE, IPH, &OptInfo,
  2315. DestType, NULL, 0, FALSE);
  2316. if (NewDType != DEST_LOCAL) {
  2317. if (NewDType == DEST_REMOTE)
  2318. goto forward;
  2319. else {
  2320. IPSInfo.ipsi_inhdrerrors++;
  2321. CTEFreeMem(PreservedData);
  2322. return; // Bad Options.
  2323. }
  2324. }
  2325. }
  2326. RcvBuf.ipr_next = NULL;
  2327. RcvBuf.ipr_owner = IPR_OWNER_STACK;
  2328. RcvBuf.ipr_buffer = (uchar *) Data;
  2329. RcvBuf.ipr_size = IPDataLength;
  2330. RcvBuf.ipr_flags = 0;
  2331. RcvBuf.ipr_pMdl = NULL;
  2332. RcvBuf.ipr_pClientCnt = NULL;
  2333. // When we get here, we have the whole packet. Deliver
  2334. // it.
  2335. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  2336. DeliverToUser(NTE, DestNTE, IPH, HeaderLength, &RcvBuf,
  2337. IPDataLength, &OptInfo, NULL, DestType);
  2338. // When we're here, we're through with the packet
  2339. // locally. If it's a broadcast packet forward it on.
  2340. if (IS_BCAST_DEST(DestType)) {
  2341. IPForwardPkt(NTE, IPH, HeaderLength, Data, IPDataLength, NULL, 0, DestType, 0, NULL, NULL, LinkCtxt);
  2342. }
  2343. KeLowerIrql(OldIrql);
  2344. // free the data, work item and various fields within them.
  2345. CTEFreeMem(PreservedData);
  2346. return;
  2347. }
  2348. // Not for us, may need to be forwarded. It might be an outgoing
  2349. // broadcast that came in through a source route, so we need to
  2350. // check that.
  2351. forward:
  2352. if (DestType != DEST_INVALID) {
  2353. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  2354. IPForwardPkt(NTE, IPH, HeaderLength, Data, DataSize,
  2355. NULL, 0, DestType, 0, NULL, NULL, LinkCtxt);
  2356. KeLowerIrql(OldIrql);
  2357. } else
  2358. IPSInfo.ipsi_inaddrerrors++;
  2359. // free the data, work item and various fields within them.
  2360. CTEFreeMem(PreservedData);
  2361. return;
  2362. } // Bad Version
  2363. } // Bad checksum
  2364. } // No data
  2365. IPSInfo.ipsi_inhdrerrors++;
  2366. // free the data, work item and various fields within them.
  2367. CTEFreeMem(PreservedData);
  2368. }
  2369. //* IPRcvPacket - Receive an incoming IP datagram along with the ndis packet
  2370. //
  2371. // This is the routine called by the link layer module when an incoming IP
  2372. // datagram is to be processed. We validate the datagram (including doing
  2373. // the xsum), copy and process incoming options, and decide what to do
  2374. // with it.
  2375. //
  2376. // Entry: MyContext - The context valued we gave to the link layer.
  2377. // Data - Pointer to the data buffer.
  2378. // DataSize - Size in bytes of the data buffer.
  2379. // TotalSize - Total size in bytes available.
  2380. // LContext1 - 1st link context.
  2381. // LContext2 - 2nd link context.
  2382. // BCast - Indicates whether or not packet was received
  2383. // on bcast address.
  2384. // HeaderSize - size of the mac header
  2385. // pMdl - NDIS Packet from the MAC driver
  2386. // pClientCnt - Variable to indicate how many upper layer
  2387. // clients were given this packet
  2388. // for TCP it will be only 1.
  2389. //
  2390. // Returns: Nothing.
  2391. //
  2392. void
  2393. __stdcall
  2394. IPRcvPacket(void *MyContext, void *Data, uint DataSize, uint TotalSize,
  2395. NDIS_HANDLE LContext1, uint LContext2, uint BCast,
  2396. uint MacHeaderSize, PNDIS_BUFFER pNdisBuffer, uint *pClientCnt,
  2397. LinkEntry *LinkCtxt)
  2398. {
  2399. IPHeader UNALIGNED *IPH = (IPHeader UNALIGNED *) Data;
  2400. NetTableEntry *NTE = (NetTableEntry *) MyContext; // Local NTE received on
  2401. NetTableEntry *DestNTE; // NTE to receive on.
  2402. Interface *RcvIF = NULL; // Interface corresponding to NTE.
  2403. PNDIS_PACKET TDPacket = NULL; // NDIS packet used for TD.
  2404. TDContext *TDC = (TDContext *) NULL; // Transfer data context.
  2405. NDIS_STATUS Status;
  2406. IPAddr DAddr; // Dest. IP addr. of received packet.
  2407. uint HeaderLength; // Size in bytes of received header.
  2408. uint IPDataLength; // Length in bytes of IP (including UL)
  2409. // data in packet.
  2410. IPOptInfo OptInfo; // Incoming header information.
  2411. uchar DestType; // Type (LOCAL, REMOTE, SR) of Daddr.
  2412. IPRcvBuf RcvBuf;
  2413. BOOLEAN ChkSumOk = FALSE;
  2414. // used by firewall
  2415. uchar NewDType;
  2416. IPRcvBuf *pRcvBuf;
  2417. uint MoreData = 0;
  2418. uchar *PreservedData;
  2419. uchar *HdrBuf;
  2420. uint DataLength;
  2421. uint FirewallMode = 0;
  2422. uint PromiscuousMode = 0;
  2423. uint AbsorbFwdPkt = 0;
  2424. PNDIS_PACKET OffLoadPkt = NULL;
  2425. BOOLEAN Loopback = FALSE;
  2426. IPSIncrementInReceiveCount();
  2427. // Make sure we actually have data.
  2428. if (0 == DataSize) {
  2429. goto HeaderError;
  2430. }
  2431. // Check the header length, the xsum and the version. If any of these
  2432. // checks fail silently discard the packet.
  2433. HeaderLength = ((IPH->iph_verlen & (uchar)~IP_VER_FLAG) << 2);
  2434. if ((HeaderLength < sizeof(IPHeader)) || (HeaderLength > DataSize)) {
  2435. goto HeaderError;
  2436. }
  2437. //Check if hardware did the checksum or not by inspecting Lcontext1
  2438. if (pClientCnt) {
  2439. PNDIS_PACKET_EXTENSION PktExt;
  2440. NDIS_TCP_IP_CHECKSUM_PACKET_INFO ChksumPktInfo;
  2441. if (pNdisBuffer) {
  2442. OffLoadPkt = NDIS_GET_ORIGINAL_PACKET((PNDIS_PACKET) (LContext1));
  2443. if (!OffLoadPkt) {
  2444. OffLoadPkt = (PNDIS_PACKET) (LContext1);
  2445. }
  2446. } else {
  2447. OffLoadPkt = (PNDIS_PACKET) pClientCnt;
  2448. }
  2449. PktExt = NDIS_PACKET_EXTENSION_FROM_PACKET(OffLoadPkt);
  2450. ChksumPktInfo.Value = PtrToUshort(PktExt->NdisPacketInfo[TcpIpChecksumPacketInfo]);
  2451. if (ChksumPktInfo.Value) {
  2452. if (ChksumPktInfo.Receive.NdisPacketIpChecksumSucceeded) {
  2453. ChkSumOk = TRUE;
  2454. }
  2455. }
  2456. //
  2457. // Check if this packet is an echo of packet that we sent.
  2458. //
  2459. Loopback = (NdisGetPacketFlags(OffLoadPkt) & NDIS_FLAGS_IS_LOOPBACK_PACKET)?TRUE : FALSE;
  2460. }
  2461. // Unless the hardware says the checksum was correct, checksum the
  2462. // header ourselves and bail out if it is incorrect.
  2463. if (!ChkSumOk && (xsum(Data, HeaderLength) != (ushort) 0xffff)) {
  2464. goto HeaderError;
  2465. }
  2466. // Check the version, and sanity check the total length.
  2467. IPDataLength = (uint) net_short(IPH->iph_length);
  2468. if (((IPH->iph_verlen & IP_VER_FLAG) != IP_VERSION) ||
  2469. (IPDataLength < HeaderLength) || (IPDataLength > TotalSize)) {
  2470. goto HeaderError;
  2471. }
  2472. IPDataLength -= HeaderLength;
  2473. // In case of firewall, we need to pass the whole data including header
  2474. PreservedData = (uchar *) Data;
  2475. Data = (uchar *) Data + HeaderLength;
  2476. DataSize -= HeaderLength;
  2477. DAddr = IPH->iph_dest;
  2478. DestNTE = NTE;
  2479. // Find local NTE, if any.
  2480. if (BCast == AI_PROMIS_INDEX) {
  2481. DestType = DEST_PROMIS;
  2482. } else {
  2483. DestType = GetLocalNTE(DAddr, &DestNTE);
  2484. }
  2485. AbsorbFwdPkt = (DestType >= DEST_REMOTE) &&
  2486. (NTE->nte_if->if_absorbfwdpkts) &&
  2487. (IPH->iph_protocol == NTE->nte_if->if_absorbfwdpkts) &&
  2488. IsRtrAlertPacket(IPH);
  2489. PromiscuousMode = NTE->nte_if->if_promiscuousmode;
  2490. FirewallMode = ProcessFirewallQ();
  2491. // Check to see if this is a non-broadcast IP address that
  2492. // came in as a link layer broadcast. If it is, throw it out.
  2493. // This is an important check for DHCP, since if we're
  2494. // DHCPing an interface all otherwise unknown addresses will
  2495. // come in as DEST_LOCAL. This check here will throw them out
  2496. // if they didn't come in as unicast.
  2497. if ((BCast == AI_NONUCAST_INDEX) && !IS_BCAST_DEST(DestType)) {
  2498. IPSInfo.ipsi_inaddrerrors++;
  2499. return; // Non bcast packet on bcast address.
  2500. }
  2501. if (CLASSD_ADDR(DAddr)) {
  2502. NTE->nte_if->if_InMcastPkts++;
  2503. NTE->nte_if->if_InMcastOctets += IPDataLength;
  2504. }
  2505. OptInfo.ioi_ttl = IPH->iph_ttl;
  2506. OptInfo.ioi_tos = IPH->iph_tos;
  2507. OptInfo.ioi_flags = (uchar) ((net_short(IPH->iph_offset) >> 13) & IP_FLAG_DF);
  2508. OptInfo.ioi_options = (uchar *) NULL;
  2509. OptInfo.ioi_optlength = 0;
  2510. if ((DestType < DEST_REMOTE) || (AbsorbFwdPkt) ||
  2511. (((FirewallMode) || (PromiscuousMode)) && (DestType != DEST_INVALID)))
  2512. {
  2513. // It's either local or some sort of broadcast.
  2514. // The data probably belongs at this station. If there
  2515. // aren't any options, it definitely belongs here, and we'll
  2516. // dispatch it either to our reassembly code or to the
  2517. // deliver to user code. If there are options, we'll check
  2518. // them and then either handle the packet locally or pass it
  2519. // to our forwarding code.
  2520. NewDType = DestType;
  2521. if (DestType < DEST_REMOTE) {
  2522. if (HeaderLength != sizeof(IPHeader)) {
  2523. // We have options.
  2524. NewDType = CheckLocalOptions(NTE, IPH, &OptInfo, DestType,
  2525. Data, DataSize, TRUE);
  2526. if (NewDType != DEST_LOCAL) {
  2527. if (NewDType == DEST_REMOTE) {
  2528. if ((!FirewallMode) && (!PromiscuousMode) && (!AbsorbFwdPkt))
  2529. goto forward;
  2530. else
  2531. DestType = NewDType;
  2532. } else {
  2533. goto HeaderError;
  2534. }
  2535. }
  2536. if ((OptInfo.ioi_flags & IP_FLAG_SSRR) &&
  2537. DisableIPSourceRouting == 2) {
  2538. IPSInfo.ipsi_outdiscards++;
  2539. if (RefPtrValid(&FilterRefPtr)) {
  2540. NotifyFilterOfDiscard(NTE, IPH, Data, DataSize);
  2541. }
  2542. return;
  2543. }
  2544. }
  2545. }
  2546. //
  2547. // Before we go further, if we have a filter installed
  2548. // call it to see if we should take this.
  2549. // if ForwardFirewall/Promiscuous, we can reach at this
  2550. // point
  2551. // if firewall/ipsec/promiscuous present, we will call
  2552. // filter hook in delivertouserex
  2553. // Except if we have a fragment, we also call filter hook
  2554. // now.
  2555. //
  2556. if (((RefPtrValid(&FilterRefPtr)) && (!IPSecHandlerPtr) &&
  2557. (!FirewallMode) && (!PromiscuousMode) &&
  2558. (!AbsorbFwdPkt)) ||
  2559. ((RefPtrValid(&FilterRefPtr)) &&
  2560. (IPH->iph_offset & ~(IP_DF_FLAG | IP_RSVD_FLAG)))) {
  2561. Interface *IF = NTE->nte_if;
  2562. IPAddr LinkNextHop;
  2563. IPPacketFilterPtr FilterPtr;
  2564. FORWARD_ACTION Action;
  2565. if ((IF->if_flags & IF_FLAGS_P2MP) && LinkCtxt) {
  2566. LinkNextHop = LinkCtxt->link_NextHop;
  2567. } else {
  2568. LinkNextHop = NULL_IP_ADDR;
  2569. }
  2570. FilterPtr = AcquireRefPtr(&FilterRefPtr);
  2571. Action = (*FilterPtr) (IPH,
  2572. Data,
  2573. MIN(DataSize, IPDataLength),
  2574. IF->if_index,
  2575. INVALID_IF_INDEX,
  2576. LinkNextHop,
  2577. NULL_IP_ADDR);
  2578. ReleaseRefPtr(&FilterRefPtr);
  2579. if (Action != FORWARD) {
  2580. IPSInfo.ipsi_indiscards++;
  2581. return;
  2582. }
  2583. }
  2584. // No options. See if it's a fragment. If it is, call our
  2585. // reassembly handler.
  2586. if ((IPH->iph_offset & ~(IP_DF_FLAG | IP_RSVD_FLAG)) == 0) {
  2587. // We don't have a fragment. If the data all fits,
  2588. // handle it here. Otherwise transfer data it.
  2589. // Make sure data is all in buffer, and directly
  2590. // accesible.
  2591. if ((IPDataLength > DataSize) || !(NTE->nte_flags & NTE_COPY))
  2592. {
  2593. // The data isn't all here. Transfer data it.
  2594. // Needed by firewall since we need to attach the IPheader
  2595. MoreData = 1;
  2596. RcvIF = NTE->nte_if;
  2597. CTEGetLockAtDPC(&RcvIF->if_lock);
  2598. TDPacket = RcvIF->if_tdpacket;
  2599. if (TDPacket != (PNDIS_PACKET) NULL) {
  2600. TDC = (TDContext *) TDPacket->ProtocolReserved;
  2601. RcvIF->if_tdpacket = TDC->tdc_common.pc_link;
  2602. CTEFreeLockFromDPC(&RcvIF->if_lock);
  2603. TDC->tdc_nte = DestNTE;
  2604. TDC->tdc_dtype = DestType;
  2605. TDC->tdc_hlength = (uchar) HeaderLength;
  2606. RtlCopyMemory(TDC->tdc_header, IPH,
  2607. HeaderLength + 8);
  2608. Status = (*(RcvIF->if_transfer)) (
  2609. RcvIF->if_lcontext, LContext1,
  2610. LContext2, HeaderLength,
  2611. IPDataLength, TDPacket,
  2612. &IPDataLength);
  2613. // Check the status. If it's success, call the
  2614. // receive procedure. Otherwise, if it's pending
  2615. // wait for the callback.
  2616. Data = TDC->tdc_buffer;
  2617. if (Status != NDIS_STATUS_PENDING) {
  2618. if (Status != NDIS_STATUS_SUCCESS) {
  2619. IPSInfo.ipsi_indiscards++;
  2620. CTEGetLockAtDPC(&RcvIF->if_lock);
  2621. TDC->tdc_common.pc_link =
  2622. RcvIF->if_tdpacket;
  2623. RcvIF->if_tdpacket = TDPacket;
  2624. CTEFreeLockFromDPC(&RcvIF->if_lock);
  2625. return;
  2626. }
  2627. } else {
  2628. return; // Status is pending.
  2629. }
  2630. } else { // Couldn't get a packet.
  2631. IPSInfo.ipsi_indiscards++;
  2632. CTEFreeLockFromDPC(&RcvIF->if_lock);
  2633. return;
  2634. }
  2635. }
  2636. if (!FirewallMode) {
  2637. // fast path
  2638. RcvBuf.ipr_next = NULL;
  2639. RcvBuf.ipr_owner = IPR_OWNER_STACK;
  2640. RcvBuf.ipr_buffer = (uchar *) Data;
  2641. RcvBuf.ipr_size = IPDataLength;
  2642. RcvBuf.ipr_flags = 0;
  2643. //
  2644. // Encapsulate the mdl and context info in RcvBuf
  2645. // structure if TD Packet is not involved.
  2646. //
  2647. RcvBuf.ipr_pMdl = NULL;
  2648. RcvBuf.ipr_pClientCnt = NULL;
  2649. if (!MoreData) {
  2650. RcvBuf.ipr_pMdl = pNdisBuffer;
  2651. RcvBuf.ipr_pClientCnt = pClientCnt;
  2652. }
  2653. RcvBuf.ipr_RcvContext = (uchar *)LContext1;
  2654. //ASSERT(LContext2 <= 8);
  2655. RcvBuf.ipr_RcvOffset = MacHeaderSize +
  2656. HeaderLength + LContext2;
  2657. DataLength = IPDataLength;
  2658. pRcvBuf = &RcvBuf;
  2659. } else { // ForwardFirewallPtr != NULL
  2660. //
  2661. // if Firewall hooks are present we will allocate
  2662. // RcvBuf. Also we will pass IPHeader to
  2663. // DelivertoUserEx
  2664. if (!MoreData) {
  2665. if (g_PerCPUIpBuf) {
  2666. pRcvBuf = g_PerCPUIpBuf + KeGetCurrentProcessorNumber();
  2667. pRcvBuf->ipr_owner = IPR_OWNER_STACK;
  2668. } else {
  2669. pRcvBuf = (IPRcvBuf *) CTEAllocMemN(sizeof(IPRcvBuf), 'jiCT');
  2670. if (!pRcvBuf) {
  2671. IPSInfo.ipsi_indiscards++;
  2672. return;
  2673. }
  2674. pRcvBuf->ipr_owner = IPR_OWNER_FIREWALL;
  2675. }
  2676. pRcvBuf->ipr_next = NULL;
  2677. pRcvBuf->ipr_buffer = (uchar *) PreservedData;
  2678. pRcvBuf->ipr_size = IPDataLength + HeaderLength;
  2679. pRcvBuf->ipr_flags = 0;
  2680. //
  2681. // Encapsulate the mdl and context info in
  2682. // RcvBuf structure
  2683. //
  2684. pRcvBuf->ipr_pMdl = NULL;
  2685. pRcvBuf->ipr_pClientCnt = NULL;
  2686. //
  2687. // Enable Buffer ownership in Firewall mode
  2688. // When re-route lookup results in forwarding
  2689. // local packets, this will help firwall clients
  2690. // like proxy/nat to use super fast path in
  2691. // IPForwardPkt().
  2692. //
  2693. if (DestType < DEST_REMOTE) {
  2694. pRcvBuf->ipr_pMdl = pNdisBuffer;
  2695. pRcvBuf->ipr_pClientCnt = pClientCnt;
  2696. }
  2697. pRcvBuf->ipr_RcvContext = (uchar *)LContext1;
  2698. pRcvBuf->ipr_RcvOffset = MacHeaderSize + HeaderLength + LContext2;
  2699. } else { // MoreData=1; we have gone thru TD
  2700. // path attach the header
  2701. pRcvBuf = (IPRcvBuf *) CTEAllocMemN(sizeof(IPRcvBuf), 'jiCT');
  2702. if (!pRcvBuf) {
  2703. IPSInfo.ipsi_indiscards++;
  2704. return;
  2705. }
  2706. pRcvBuf->ipr_owner = IPR_OWNER_FIREWALL;
  2707. HdrBuf = (uchar *) CTEAllocMemN(HeaderLength, 'kiCT');
  2708. if (!HdrBuf) {
  2709. CTEFreeMem(pRcvBuf);
  2710. IPSInfo.ipsi_indiscards++;
  2711. return;
  2712. }
  2713. RtlCopyMemory(HdrBuf, IPH, HeaderLength);
  2714. pRcvBuf->ipr_buffer = HdrBuf; // remember to
  2715. // free HdrBuf &
  2716. //pRcvBuf
  2717. pRcvBuf->ipr_size = HeaderLength;
  2718. pRcvBuf->ipr_flags = 0;
  2719. pRcvBuf->ipr_pMdl = NULL;
  2720. pRcvBuf->ipr_pClientCnt = NULL;
  2721. pRcvBuf->ipr_next = (IPRcvBuf *) CTEAllocMemN(sizeof(IPRcvBuf), 'liCT');
  2722. if (!pRcvBuf->ipr_next) {
  2723. CTEFreeMem(pRcvBuf);
  2724. CTEFreeMem(HdrBuf);
  2725. IPSInfo.ipsi_indiscards++;
  2726. return;
  2727. }
  2728. pRcvBuf->ipr_next->ipr_next = NULL;
  2729. pRcvBuf->ipr_next->ipr_owner = IPR_OWNER_IP;
  2730. pRcvBuf->ipr_next->ipr_buffer = (uchar *) Data;
  2731. pRcvBuf->ipr_next->ipr_size = IPDataLength;
  2732. //
  2733. //encapsulate the mdl and context info in
  2734. //RcvBuf structure
  2735. //
  2736. pRcvBuf->ipr_next->ipr_pMdl = NULL;
  2737. pRcvBuf->ipr_next->ipr_pClientCnt = NULL;
  2738. pRcvBuf->ipr_next->ipr_RcvContext = (uchar *)LContext1;
  2739. pRcvBuf->ipr_next->ipr_flags = 0;
  2740. //ASSERT(LContext2 <= 8);
  2741. pRcvBuf->ipr_next->ipr_RcvOffset =
  2742. MacHeaderSize + HeaderLength + LContext2;
  2743. }
  2744. // In case of firewall, Data includes ipheader also
  2745. DataLength = IPDataLength + HeaderLength;
  2746. }
  2747. // 3 cases when we go to DeliverToUserEx
  2748. // IPSEC & Filter present; Firewallhooks present;
  2749. // promiscuous mode set on the interface
  2750. if (((IPSecHandlerPtr) && (RefPtrValid(&FilterRefPtr))) ||
  2751. (FirewallMode) || (PromiscuousMode)) {
  2752. if (Loopback) {
  2753. //
  2754. // Loopbacked packet should not end up getting
  2755. // forwarded again to prevent nested receive
  2756. // indications from ndis, causing stack overflow.
  2757. //
  2758. pRcvBuf->ipr_flags |= IPR_FLAG_LOOPBACK_PACKET;
  2759. }
  2760. if (pClientCnt) {
  2761. DeliverToUserEx(NTE, DestNTE, IPH, HeaderLength,
  2762. pRcvBuf, DataLength, &OptInfo,
  2763. LContext1, DestType, LinkCtxt);
  2764. } else {
  2765. DeliverToUserEx(NTE, DestNTE, IPH, HeaderLength,
  2766. pRcvBuf, DataLength, &OptInfo,
  2767. NULL, DestType, LinkCtxt);
  2768. }
  2769. } else {
  2770. //
  2771. // When we get here, we have the whole packet.
  2772. // Deliver it.
  2773. //
  2774. if (pNdisBuffer) {
  2775. DeliverToUser(NTE, DestNTE, IPH, HeaderLength,
  2776. pRcvBuf, IPDataLength, &OptInfo,
  2777. (PNDIS_PACKET) (LContext1),
  2778. DestType);
  2779. } else if (OffLoadPkt) {
  2780. DeliverToUser(NTE, DestNTE, IPH, HeaderLength, pRcvBuf,
  2781. IPDataLength, &OptInfo, OffLoadPkt, DestType);
  2782. } else {
  2783. DeliverToUser(
  2784. NTE, DestNTE, IPH, HeaderLength, pRcvBuf,
  2785. IPDataLength, &OptInfo, NULL, DestType);
  2786. }
  2787. //
  2788. // When we're here, we're through with the packet
  2789. // locally. If it's a broadcast packet forward it
  2790. // on.
  2791. if (IS_BCAST_DEST(DestType)) {
  2792. IPForwardPkt(NTE, IPH, HeaderLength, Data,
  2793. IPDataLength, NULL, 0, DestType,
  2794. 0, NULL, NULL, LinkCtxt);
  2795. }
  2796. }
  2797. if (TDC != NULL) {
  2798. CTEGetLockAtDPC(&RcvIF->if_lock);
  2799. TDC->tdc_common.pc_link = RcvIF->if_tdpacket;
  2800. RcvIF->if_tdpacket = TDPacket;
  2801. CTEFreeLockFromDPC(&RcvIF->if_lock);
  2802. }
  2803. return;
  2804. } else {
  2805. // This is a fragment. Reassemble it.
  2806. IPReassemble(NTE, DestNTE, IPH, HeaderLength, Data,
  2807. DataSize, IPDataLength, DestType, LContext1,
  2808. LContext2, LinkCtxt);
  2809. return;
  2810. }
  2811. }
  2812. // Not for us, may need to be forwarded. It might be an outgoing
  2813. // broadcast that came in through a source route, so we need to
  2814. // check that.
  2815. forward:
  2816. if (DestType != DEST_INVALID) {
  2817. //
  2818. // If IPSec is active, make sure there are no inbound policies
  2819. // that apply to this packet.
  2820. // N.B - IPSecStatus will be true if there is at least one ipsec policy.
  2821. //
  2822. if (IPSecStatus &&
  2823. (*IPSecRcvFWPacketPtr)((PCHAR) IPH, Data, DataSize, DestType) != eFORWARD) {
  2824. IPSInfo.ipsi_indiscards++;
  2825. return;
  2826. }
  2827. // Super Fast Forward
  2828. // chk the parameters
  2829. IPForwardPkt(NTE, IPH, HeaderLength, Data, DataSize,
  2830. LContext1, LContext2, DestType, MacHeaderSize, pNdisBuffer,
  2831. pClientCnt, LinkCtxt);
  2832. } else {
  2833. IPSInfo.ipsi_inaddrerrors++;
  2834. }
  2835. return;
  2836. HeaderError:
  2837. IPSInfo.ipsi_inhdrerrors++;
  2838. }
  2839. //* IPRcv - Receive an incoming IP datagram.
  2840. //
  2841. // This is the routine called by the link layer module when an incoming IP
  2842. // datagram is to be processed. We validate the datagram (including doing
  2843. // the xsum), copy and process incoming options, and decide what to do with it.
  2844. //
  2845. // Entry: MyContext - The context valued we gave to the link layer.
  2846. // Data - Pointer to the data buffer.
  2847. // DataSize - Size in bytes of the data buffer.
  2848. // TotalSize - Total size in bytes available.
  2849. // LContext1 - 1st link context.
  2850. // LContext2 - 2nd link context.
  2851. // BCast - Indicates whether or not packet was received on bcast address.
  2852. //
  2853. // Returns: Nothing.
  2854. //
  2855. // For buffer ownership version, we just call RcvPacket, with additional
  2856. // two null arguments. Currently LANARP supports buffer owner ship.
  2857. // Rest of the folks (rasarp, wanarp and atmarp) come this way.
  2858. //
  2859. void
  2860. __stdcall
  2861. IPRcv(void *MyContext, void *Data, uint DataSize, uint TotalSize,
  2862. NDIS_HANDLE LContext1, uint LContext2, uint BCast, LinkEntry * LinkCtxt)
  2863. {
  2864. IPRcvPacket(MyContext,
  2865. Data,
  2866. DataSize,
  2867. TotalSize,
  2868. LContext1,
  2869. LContext2,
  2870. BCast,
  2871. (uint) 0,
  2872. NULL,
  2873. NULL,
  2874. LinkCtxt);
  2875. }
  2876. //* IPTDComplete - IP Transfer data complete handler.
  2877. //
  2878. // This is the routine called by the link layer when a transfer data completes.
  2879. //
  2880. // Entry: MyContext - Context value we gave to the link layer.
  2881. // Packet - Packet we originally gave to transfer data.
  2882. // Status - Final status of command.
  2883. // BytesCopied - Number of bytes copied.
  2884. //
  2885. // Exit: Nothing
  2886. //
  2887. void
  2888. __stdcall
  2889. IPTDComplete(void *MyContext, PNDIS_PACKET Packet, NDIS_STATUS Status,
  2890. uint BytesCopied)
  2891. {
  2892. TDContext *TDC = (TDContext *) Packet->ProtocolReserved;
  2893. FWContext *pFWC = (FWContext *) Packet->ProtocolReserved;
  2894. NetTableEntry *NTE = (NetTableEntry *) MyContext;
  2895. uint PromiscuousMode = 0;
  2896. uint FirewallMode = 0;
  2897. if (NTE->nte_flags & NTE_VALID) {
  2898. PromiscuousMode = NTE->nte_if->if_promiscuousmode;
  2899. FirewallMode = ProcessFirewallQ();
  2900. }
  2901. if (((IPSecHandlerPtr) && (RefPtrValid(&FilterRefPtr))) ||
  2902. (FirewallMode) || (PromiscuousMode)) {
  2903. if (!(TDC->tdc_common.pc_flags & PACKET_FLAG_RA))
  2904. TDUserRcv(MyContext, Packet, Status, BytesCopied);
  2905. else
  2906. RATDComplete(MyContext, Packet, Status, BytesCopied);
  2907. } else { // Normal Path
  2908. if (!(TDC->tdc_common.pc_flags & PACKET_FLAG_FW))
  2909. if (!(TDC->tdc_common.pc_flags & PACKET_FLAG_RA))
  2910. TDUserRcv(MyContext, Packet, Status, BytesCopied);
  2911. else
  2912. RATDComplete(MyContext, Packet, Status, BytesCopied);
  2913. else {
  2914. #if IPMCAST
  2915. if (pFWC->fc_dtype == DEST_REM_MCAST) {
  2916. IPMForwardAfterTD(MyContext, Packet, BytesCopied);
  2917. return;
  2918. }
  2919. #endif
  2920. SendFWPacket(Packet, Status, BytesCopied);
  2921. }
  2922. }
  2923. }
  2924. //* IPFreeBuff -
  2925. // Frees the chain and the buffers associated with the chain if allocated
  2926. // by firewall hook
  2927. //
  2928. //
  2929. void
  2930. IPFreeBuff(IPRcvBuf * pRcvBuf)
  2931. {
  2932. IPRcvBuf *Curr = pRcvBuf;
  2933. IPRcvBuf *Prev;
  2934. //
  2935. // Free all blocks carried by pRcvbuf
  2936. //
  2937. while (pRcvBuf != NULL) {
  2938. FreeIprBuff(pRcvBuf);
  2939. pRcvBuf = pRcvBuf->ipr_next;
  2940. }
  2941. while (Curr != NULL) {
  2942. Prev = Curr;
  2943. Curr = Curr->ipr_next;
  2944. //
  2945. // Free pRcvBuf itself
  2946. // if it is not allocated
  2947. // on the stack.
  2948. //
  2949. if (Prev->ipr_owner != IPR_OWNER_STACK) {
  2950. CTEFreeMem(Prev);
  2951. }
  2952. }
  2953. }
  2954. //* FreeIprBuff -
  2955. // Frees the buffer associated by IPRcvBuf if tag in rcvbuf is firewall
  2956. // The idea is that if the buffer is allocated by firewall, the tag is firewall
  2957. // and its freed when we call ipfreebuff or this routine. However, there is a
  2958. // slight catch here. In the reassembly path, the buffer is tagged as ip but
  2959. // it has to be freed by ip driver only since the reassembly buffers are
  2960. // allocated by ip only. But in this case, the flat buffer is part of the
  2961. // Rcvbuf structure and so when Rcvbuf structure is freed the flat buffer is
  2962. // also freed. In other cases, fast path in Rcv and xmit path, respective
  2963. // lower and upper layers free the flat buffer. This makes sure that ip is
  2964. // not freeing the buffers which some other layer allocates. This technique
  2965. // is now used by IPSEC also.
  2966. //
  2967. void
  2968. FreeIprBuff(IPRcvBuf * pRcvBuf)
  2969. {
  2970. ASSERT(pRcvBuf != NULL);
  2971. if ((pRcvBuf->ipr_buffer != NULL) && (pRcvBuf->ipr_owner == IPR_OWNER_FIREWALL)) {
  2972. CTEFreeMem(pRcvBuf->ipr_buffer);
  2973. }
  2974. }
  2975. //* IPAllocBuff -
  2976. // Allocates a buffer of given size and attaches it to IPRcvBuf
  2977. //
  2978. // Returns: TRUE if success else FALSE
  2979. //
  2980. int
  2981. IPAllocBuff(IPRcvBuf * pRcvBuf, uint size)
  2982. {
  2983. ASSERT(pRcvBuf != NULL);
  2984. // put a tag in iprcvbuf that firewall allocated it so that
  2985. // FreeIprBuff / IPFreeBuff can free it
  2986. pRcvBuf->ipr_owner = IPR_OWNER_FIREWALL;
  2987. if ((pRcvBuf->ipr_buffer = (uchar *) CTEAllocMemN(size, 'miCT')) == NULL) {
  2988. return FALSE;
  2989. }
  2990. return TRUE;
  2991. }